#if (FEATURE_MODE == 0)
#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
/**
 @file sys_tmm_ipfix.c

 @date 2019-7-2

 @version v1.0

 The file contains TMM IPFIX APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_ipfix.h"
#include "sys_usw_common.h"
#include "sys_usw_chip.h"
#include "sys_usw_ipfix.h"
#include "sys_usw_dma.h"
#include "sys_usw_register.h"
#include "sys_usw_packet.h"
#include "sys_usw_acl_api.h"
#include "sys_tmm_discard_type.h"
#include "drv_api.h"

#define SYS_IPFIX_DROP_CLASS_ID_CNT 32
#define SYS_IPFIX_DUMP_FLOW_CNT 256
#define SYS_IPFIX_HASH_BUCKET_NUM (DRV_FROM_AT(lchip) ? 8*1024 : 32*1024)
#define SYS_IPFIX_AD_MODULE_TYPE 3

#define SYS_IPFIX_DUMP_MAX_ENTRY_ONE_ROUND 1000
extern uint8 ctc_hash_type[];

uint8 ctc_export_reason[]={
CTC_IPFIX_NO_EXPORT,
CTC_IPFIX_REASON_EXPIRED,
CTC_IPFIX_REASON_TCP_CLOSE,
CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW,
CTC_IPFIX_REASON_DROP_CNT_OVERFLOW,
CTC_IPFIX_REASON_NEW_FLOW_INSERT,
CTC_IPFIX_REASON_DROP_REASON_CHANGE,
CTC_IPFIX_REASON_LAST_TS_OVERFLOW,
CTC_IPFIX_REASON_JITTER_OVERFLOW,
CTC_IPFIX_REASON_LATENCY_OVERFLOW,
CTC_IPFIX_REASON_TTL_CHANGE,
CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW,
CTC_IPFIX_REASON_DEST_CHANGE,
CTC_IPFIX_REASON_DUMP,
CTC_IPFIX_REASON_TC_MARK
};

extern sal_mutex_t*   p_ipfix_cb_mutex;

extern int32
_sys_usw_ipfix_unmapping_export_reason(uint8 lchip, uint8 sys_reason );
extern int32
_sys_usw_ipfix_unmapping_key_type(uint8 lchip, uint8 sys_key_type );
extern int32
_sys_usw_ipfix_delete_entry_by_index(uint8 lchip, uint8 key_type, uint32 index, uint8 dir, uint8 is_key);
extern uint32
_sys_usw_ipfix_get_tbl_id_by_dir(uint8 lchip, uint32 tbl_id, uint8 dir);
extern int32
_sys_usw_ipfix_sample_interval_convert(uint8 lchip, sys_ipfix_sample_profile_t* p_profile, uint16* drv_interval );
extern int32
sys_tmm_ipfix_set_global_cfg(uint8 lchip, void* cfg);
extern int32
sys_usw_packet_usr_rx_cb(uint8 lchip, ctc_pkt_rx_t* p_pkt_rx);
extern int32
sys_tmm_ipfix_cb_init(uint8 lchip);
extern int32
_sys_usw_ipfix_encode_l2_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_l2l3_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_ipv4_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_ipv6_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_mpls_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_set_l2_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_l2l3_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_ipv4_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_ipv6_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_l2l3_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_mpls_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_mac_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_l2l3_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_v4_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_v6_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_mpls_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_udf_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
sys_usw_set_monitor_drop_discard_enable(uint8 lchip, uint8 enable);

extern int32
sys_usw_packet_usr_rx_cb(uint8 lchip, ctc_pkt_rx_t* p_pkt_rx);
#define SYS_USW_SET_HW_UDF_SHORT(lchip, dest, src)     \
    {\
        (dest)[2] = ((src)[10] << 24 | src[11] << 16 | src[8] << 8 | src[9]);        \
        (dest)[1] = ((src)[6] << 24 | src[7] << 16 | src[4] << 8 | src[5]);           \
        (dest)[0] = ((src)[2] << 24 | src[3] << 16 | src[0] << 8 | src[1]);           \
    }


#define IPFIX_TMM_TRAVERSE_TYPE_PROCESS(dump_info, key_type, is_remove,dir)\
        do{\
                    if(is_remove)\
                    {\
                        if(CTC_E_NONE == ((ctc_ipfix_traverse_remove_cmp)fn)(&ipfix_data, p_data->user_data))\
                        {\
                            CTC_ERROR_DUMP(_sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index,dir, 1));\
                            CTC_ERROR_DUMP(_sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index,dir, 0));\
                            CTC_ERROR_DUMP(_sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index, CTC_EGRESS, 0));\
                        }\
                    }\
                    else if(traverse_action == SYS_IPFIX_DUMP_ENYRY_INFO)\
                        {\
                            ((ctc_ipfix_traverse_fn)fn)(&ipfix_data, &dump_info);\
                        }\
                        else\
                        {\
                            ((ctc_ipfix_traverse_fn)fn)(&ipfix_data, p_data->user_data);\
                        }\
        }while(0)


int32
_sys_usw_ipfix_mapping_ctc_to_sys_export_reason(uint8 lchip, uint8 ctc_reason)
{
    switch(ctc_reason)
    {
        case CTC_IPFIX_REASON_EXPIRED:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_EXPIRED);
        case CTC_IPFIX_REASON_TCP_CLOSE:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_TCP_SESSION_CLOSE);
        case CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_PACKET_COUNT_OVERFLOW);
        case CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_BYTE_COUNT_OVERFLOW);
        case CTC_IPFIX_REASON_NEW_FLOW_INSERT:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_NEW_FLOW_EXPORT);
        case CTC_IPFIX_REASON_DEST_CHANGE:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_DESTINATION_CHANGE);
        case CTC_IPFIX_REASON_LAST_TS_OVERFLOW:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_TS_COUNT_OVERFLOW);
        case CTC_IPFIX_REASON_JITTER_OVERFLOW:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_JITTER_OVERFLOW);
        case CTC_IPFIX_REASON_LATENCY_OVERFLOW:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_LATENCY_OVERFLOW);
        case CTC_IPFIX_REASON_TTL_CHANGE:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_TTL_CHANGE);
        case CTC_IPFIX_REASON_DROP_CNT_OVERFLOW:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_DROP_PKT_COUNT_OVERFLOW);
        case CTC_IPFIX_REASON_DROP_REASON_CHANGE:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_PACKET_DISCARDTYPE_CHANGE);
        case CTC_IPFIX_REASON_DUMP:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_FLUSH_TIMER_EXPORT);
        case CTC_IPFIX_REASON_LATENCY_EVENT:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_LATENCY_EVENT);
        case CTC_IPFIX_REASON_BURST_EVENT:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_BURST_EVENT);
        case CTC_IPFIX_REASON_TC_MARK:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_SESSION_PACKET_DROP);
        case CTC_IPFIX_REASON_HASH_CONFLICT:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_HASH_CONFLICT_EXPORT);
        case CTC_IPFIX_REASON_BUFFER_DROP:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_BUFFER_DROP);
        default:
            return DRV_CONST(DRV_IPFIX_EXPORTREASON_NO_EXPORT);
    }
}

int32
_sys_usw_ipfix_mapping_sys_to_ctc_export_reason(uint8 lchip, uint8 sys_reason)
{
    if(DRV_CONST(DRV_IPFIX_EXPORTREASON_EXPIRED) == sys_reason)
    {
        return CTC_IPFIX_REASON_EXPIRED;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_TCP_SESSION_CLOSE) == sys_reason)
    {
        return CTC_IPFIX_REASON_TCP_CLOSE;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_PACKET_COUNT_OVERFLOW) == sys_reason)
    {
        return CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_BYTE_COUNT_OVERFLOW) == sys_reason)
    {
        return CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_NEW_FLOW_EXPORT) == sys_reason)
    {
        return CTC_IPFIX_REASON_NEW_FLOW_INSERT;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_DESTINATION_CHANGE) == sys_reason)
    {
        return CTC_IPFIX_REASON_DEST_CHANGE;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_TS_COUNT_OVERFLOW) == sys_reason)
    {
        return CTC_IPFIX_REASON_LAST_TS_OVERFLOW;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_JITTER_OVERFLOW) == sys_reason)
    {
        return CTC_IPFIX_REASON_JITTER_OVERFLOW;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_LATENCY_OVERFLOW) == sys_reason)
    {
        return CTC_IPFIX_REASON_LATENCY_OVERFLOW;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_TTL_CHANGE) == sys_reason)
    {
        return CTC_IPFIX_REASON_TTL_CHANGE;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_DROP_PKT_COUNT_OVERFLOW) == sys_reason)
    {
        return CTC_IPFIX_REASON_DROP_CNT_OVERFLOW;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_PACKET_DISCARDTYPE_CHANGE) == sys_reason)
    {
        return CTC_IPFIX_REASON_DROP_REASON_CHANGE;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_FLUSH_TIMER_EXPORT) == sys_reason)
    {
        return CTC_IPFIX_REASON_DUMP;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_SESSION_PACKET_DROP) == sys_reason)
    {
        return CTC_IPFIX_REASON_TC_MARK;
    }
    else if (DRV_CONST(DRV_IPFIX_EXPORTREASON_BUFFER_DROP) == sys_reason)
    {
        return CTC_IPFIX_REASON_BUFFER_DROP;
    }
    else if (DRV_CONST(DRV_IPFIX_EXPORTREASON_BURST_EVENT) == sys_reason)
    {
        return CTC_IPFIX_REASON_BURST_EVENT;
    }
    else if (DRV_CONST(DRV_IPFIX_EXPORTREASON_LATENCY_EVENT) == sys_reason)
    {
        return CTC_IPFIX_REASON_LATENCY_EVENT;
    }
    else if (DRV_CONST(DRV_IPFIX_EXPORTREASON_HASH_CONFLICT_EXPORT) == sys_reason)
    {
        return CTC_IPFIX_REASON_HASH_CONFLICT;
    }
    else if(DRV_CONST(DRV_IPFIX_EXPORTREASON_NO_EXPORT) == sys_reason)
    {
        return CTC_IPFIX_NO_EXPORT;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_map_reason_ctc_to_sys_bmp(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg, uint32 * suppress_reason_bmp, uint32 * deny_export_reason_bmp)
{
    uint8   loop_i = 0;
    uint32 sys_suppress_reason_bmp = 0;
    uint32 sys_deny_export_reason_bmp = 0;

    if (CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_NO_EXPORT) ||
        CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_HASH_CONFLICT) ||
        CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_BUFFER_DROP) ||
        CTC_IS_BIT_SET(p_flow_cfg->deny_export_reason_bmp, CTC_IPFIX_NO_EXPORT) ||
        CTC_IS_BIT_SET(p_flow_cfg->deny_export_reason_bmp, CTC_IPFIX_REASON_BUFFER_DROP) ||
        CTC_IS_BIT_SET(p_flow_cfg->deny_export_reason_bmp, CTC_IPFIX_REASON_HASH_CONFLICT))
    {
        return CTC_E_INVALID_PARAM;
    }

    for (loop_i = CTC_IPFIX_REASON_EXPIRED; loop_i < CTC_IPFIX_REASON_MAX; loop_i++)
    {
        if (CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, loop_i))
        {
            CTC_BIT_SET(sys_suppress_reason_bmp, _sys_usw_ipfix_mapping_ctc_to_sys_export_reason(lchip, loop_i));
        }
        if (CTC_IS_BIT_SET(p_flow_cfg->deny_export_reason_bmp, loop_i))
        {
            CTC_BIT_SET(sys_deny_export_reason_bmp, _sys_usw_ipfix_mapping_ctc_to_sys_export_reason(lchip, loop_i));
        }
    }

    if(suppress_reason_bmp)
    {
        *suppress_reason_bmp = sys_suppress_reason_bmp;
    }
    if(deny_export_reason_bmp)
    {
        *deny_export_reason_bmp = sys_deny_export_reason_bmp;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_map_reason_sys_to_ctc_bmp(uint8 lchip, uint32 suppress_reason_bmp, uint32 deny_export_reason_bmp, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint8   loop_i = 0;
    uint32 ctc_suppress_reason_bmp = 0;
    uint32 ctc_deny_export_reason_bmp = 0;

    for (loop_i = 0; loop_i < 32; loop_i++)
    {
        if (CTC_IS_BIT_SET(suppress_reason_bmp, loop_i))
        {
            CTC_BIT_SET(ctc_suppress_reason_bmp, _sys_usw_ipfix_mapping_sys_to_ctc_export_reason(lchip, loop_i));
        }
        if (CTC_IS_BIT_SET(deny_export_reason_bmp, loop_i))
        {
            CTC_BIT_SET(ctc_deny_export_reason_bmp, _sys_usw_ipfix_mapping_sys_to_ctc_export_reason(lchip, loop_i));
        }
    }

    if(p_flow_cfg)
    {
        p_flow_cfg->suppress_reason_bmp = ctc_suppress_reason_bmp;
        p_flow_cfg->deny_export_reason_bmp = ctc_deny_export_reason_bmp;
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_get_timer_interval(uint8 lchip, uint8 is_bulk_tim, uint32* p_ctc_interval, uint32* p_sys_interval) /* ctc_interval: scan one round time; sys_interval: interval match value */
{
    uint32 core_frequecy = 0;
    uint32 ipfix_max_entry_num = 0;
    uint32 ctc_interval = 0;
    uint32 ctc_min_interval = 0;
    uint32 max_interval_s = 0;
    uint32 tick_interval = 0;
    uint64 tmp = 0;

    ctc_min_interval = is_bulk_tim ? MCHIP_CAP(SYS_CAP_IPFIX_MIN_BULK_OP_INTERVAL) : MCHIP_CAP(SYS_CAP_IPFIX_MIN_AGING_INTERVAL);
    #ifdef EMULATION_ENV
    core_frequecy = sys_usw_get_core_freq(0, 0); /* frequence: MHZ */
    #else
    core_frequecy = sys_usw_get_core_freq(lchip, 0); /* frequence: MHZ */
    #endif
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num)); /* 256k 120bit */
    ipfix_max_entry_num = (ipfix_max_entry_num/4) ? (DRV_FROM_AT(lchip)?ipfix_max_entry_num:(ipfix_max_entry_num/4)): 1;
  
    if(p_ctc_interval) /* set ctc interval */
    {
        ctc_interval = *p_ctc_interval;
        max_interval_s = (CTC_MAX_UINT32_VALUE / ((core_frequecy * 1000 * 1000 / DOWN_FRE_RATE))) * ipfix_max_entry_num * (is_bulk_tim ? 1 : 1000);
        if ((ctc_interval < ctc_min_interval) || (ctc_interval > max_interval_s))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    /* cnt*(sys_interval/f)=ctc_interval */
    tmp = (((uint64)core_frequecy * 1000*1000) / DOWN_FRE_RATE); /* frequence: HZ */
    tmp *= ctc_interval;
    tick_interval = tmp / ipfix_max_entry_num / (is_bulk_tim ? 1 : 1000); /* scan based on 480bit */
    if ((tick_interval == 0) && (ctc_interval !=0))
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"tick_interval is 0! \n");
        return CTC_E_INVALID_PARAM;
    }
    if(p_sys_interval)
    {
        *p_sys_interval = tick_interval;
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_get_timer_max_phy_ptr(uint8 lchip, uint32* p_max_phy_ptr)
{
    uint32 max_phy_ptr = 0;
    uint32 ipfix_max_entry_num = 0;

    /* max_ptr = max_phy_ptr, now ignor runfree; if need, provide again */
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num)); /* 256k 120bit */
	ipfix_max_entry_num = DRV_FROM_AT(lchip)?ipfix_max_entry_num:(ipfix_max_entry_num/4);
    max_phy_ptr = ipfix_max_entry_num - 1; /* scan based on 480bit */
    if(p_max_phy_ptr)
    {
        *p_max_phy_ptr = max_phy_ptr;
    }
    p_usw_ipfix_master[lchip]->max_ptr =  max_phy_ptr;
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_set_aging_export_timer_interval(uint8 lchip, void* p_global_cfg)
{
    uint32 cmd = 0;
    uint32 sys_export_interval = 0;
    uint32 ctc_export_interval = 100;/*default value: 100ms, and min 100ms */
    IpfixAgingTimerCtl_m  aging_timer;
    IpfixAgingTimerCtl_m  aging_timer1;
    drv_work_platform_type_t platform_type;
    ctc_ipfix_global_cfg_t* ipfix_cfg = (ctc_ipfix_global_cfg_t*)p_global_cfg;

    drv_get_platform_type(lchip, &platform_type);

    sal_memset(&aging_timer, 0, sizeof(IpfixAgingTimerCtl_m));
    sal_memset(&aging_timer1, 0, sizeof(IpfixAgingTimerCtl_m));
    ctc_export_interval = (ipfix_cfg->export_interval <= 100) ? 100: ipfix_cfg->export_interval;

    if(((0 != ipfix_cfg->aging_interval) && (ctc_export_interval > ipfix_cfg->aging_interval*1000))\
        || (ipfix_cfg->aging_interval*1000) % ctc_export_interval != 0)
    {
         return CTC_E_INVALID_PARAM;
    }

    cmd = DRV_IOR(DRV_FROM_AT(lchip)?IpfixAgingTimerCtl0_t:IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOR(IpfixAgingTimerCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer1));
    SetIpfixAgingTimerCtl(V, agingOpDisable_f, &aging_timer, (ipfix_cfg->aging_interval == 0));  /* Aging Enable */
    SetIpfixAgingTimerCtl(V, cpuAgingEn_f, &aging_timer, !!ipfix_cfg->sw_learning_en);
    SetIpfixAgingTimerCtl(V, agingOpDisable_f, &aging_timer1, (ipfix_cfg->aging_interval == 0));  /* Aging Enable */
    SetIpfixAgingTimerCtl(V, cpuAgingEn_f, &aging_timer1, !!ipfix_cfg->sw_learning_en);
    CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_interval(lchip, 0, &ctc_export_interval, &sys_export_interval));
    if (ctc_export_interval)
    {
        SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_timer, sys_export_interval);
        SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_timer1, sys_export_interval);
    }
    if (platform_type == HW_PLATFORM)
    {
        #ifdef EMULATION_ENV
        SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_timer, 100);    /* Emulation  special process due to fre down */
        SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_timer1, 100);
        #endif
        SetIpfixAgingTimerCtl(V, agingEnRoundCount_f , &aging_timer, ipfix_cfg->aging_interval*1000 / ctc_export_interval);
        SetIpfixAgingTimerCtl(V, agingEnRoundCount_f , &aging_timer1, ipfix_cfg->aging_interval*1000 / ctc_export_interval);
    }
    else
    {
        SetIpfixAgingTimerCtl(V, agingEnRoundCount_f , &aging_timer, 1);
        SetIpfixAgingTimerCtl(V, agingEnRoundCount_f , &aging_timer1, 1);
    }



    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER, 1);
    cmd = DRV_IOW( IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOW( IpfixAgingTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOW( IpfixAgingTimerCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer1));
    p_usw_ipfix_master[lchip]->export_interval = ctc_export_interval;
    p_usw_ipfix_master[lchip]->aging_interval = ipfix_cfg->aging_interval;

    return CTC_E_NONE;
}


int32
_sys_tmm_ipfix_drop_classid_spool_init(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    ctc_spool_t spool;

    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = SYS_IPFIX_DROP_CLASS_ID_CNT;
    spool.max_count = SYS_IPFIX_DROP_CLASS_ID_CNT;
    spool.user_data_size = sizeof(sys_ipfix_drop_classid_t);
    spool.key_size = CTC_OFFSET_OF(sys_ipfix_drop_classid_t, calc_key_len);
    spool.min_index = 0;
    spool.max_index = SYS_IPFIX_DROP_CLASS_ID_CNT-1;

    /*create igs drop classid spool*/
    spool.desc = "opf-ipfix-igs-drop-classid";
    p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS]= ctc_spool_create(&spool);
    if (NULL == p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS])
    {
        ret =  CTC_E_NO_MEMORY;
    }

    /*create egs drop classid spool*/
    spool.desc = "opf-ipfix-egs-drop-classid";
    p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS]= ctc_spool_create(&spool);
    if (NULL == p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS])
    {
        ret =  CTC_E_NO_MEMORY;
    }

    return ret;
}

int32
_sys_tmm_ipfix_init_drop_reason(uint8 lchip)
{
    uint8 loop_i = 0;
    uint8 index = 0;
    uint8 sys_igr_drop = 0;
    uint8 sys_egr_drop = 0;
    uint32 cmd = 0;
    uint16 ctc_drop_reason =0;
    uint32 value = 0;

    /* init IpfixEngineDiscardMapCtl0.discardTypeMap(5,0) */
    for(loop_i=SYS_TMM_DISCARD_IPE_START; loop_i<=SYS_TMM_DISCARD_IPE_END; loop_i++)
    {
        index = loop_i;
        sys_igr_drop = loop_i;
        /* Ipe */
        sys_tmm_map_drop_reason_sys_to_ctc(sys_igr_drop, &ctc_drop_reason);
        cmd = DRV_IOW(IpfixEngineDiscardMapCtl0_t, IpfixEngineDiscardMapCtl0_discardTypeMap_f);
        value = ctc_drop_reason;
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &value));

       /* Epe */
        sys_egr_drop = loop_i + (SYS_TMM_DISCARD_IPE_END + 1);
        sys_tmm_map_drop_reason_sys_to_ctc(sys_egr_drop, &ctc_drop_reason);
        cmd = DRV_IOW(IpfixEngineDiscardMapCtl1_t, IpfixEngineDiscardMapCtl1_discardTypeMap_f);
        value = ctc_drop_reason;
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &value));
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_drop_clalssid_to_reason_cb(void* node, void* user_data)
{
    sys_traverse_t* p_traverse = (sys_traverse_t*)user_data;
    uint32 drop_classid = (uint32)p_traverse->value1;
    uint32* p_ctc_drop_reaon_bmp = (uint32*)p_traverse->data;
    sys_ipfix_drop_classid_t *p_drop_classid_node = (sys_ipfix_drop_classid_t *)(((ctc_spool_node_t*)node)->data);

    if(drop_classid == p_drop_classid_node->index.index)
    {
        CTC_BMP_SET(p_ctc_drop_reaon_bmp, p_drop_classid_node->drop_reason);
    }
    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_drop_clalssid_to_reason(uint8 lchip, uint32 drop_classid_bmp, uint32* ctc_drop_reaon_bmp, uint8 dir)
{
    uint8 loop_i =0;
    sys_traverse_t user_data;

    sal_memset(&user_data, 0, sizeof(sys_traverse_t));

    for(loop_i=0; loop_i<32; loop_i++)
    {
        if(CTC_IS_BIT_SET(drop_classid_bmp, loop_i))
        {
            user_data .value1 = loop_i;  /* drop_classid*/
            user_data .data = (void*)ctc_drop_reaon_bmp;
            if(CTC_INGRESS== dir)
            {
                ctc_spool_traverse(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS], (spool_traversal_fn)_sys_tmm_ipfix_drop_clalssid_to_reason_cb, (void*) (&user_data));
            }
            else
            {
                ctc_spool_traverse(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS], (spool_traversal_fn)_sys_tmm_ipfix_drop_clalssid_to_reason_cb, (void*) (&user_data));
            }
        }
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_get_export_reason_dir(uint16 reason_id, uint8* p_dir)
{
    uint8 dir = 0;

    switch (reason_id)
    {
    case CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_DROP_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_DROP_REASON_CHANGE:
        dir = CTC_BOTH_DIRECTION;
        break;
    case CTC_IPFIX_REASON_EXPIRED:
    case CTC_IPFIX_REASON_TCP_CLOSE:
    case CTC_IPFIX_REASON_LAST_TS_OVERFLOW:
    case CTC_IPFIX_REASON_NEW_FLOW_INSERT:
    case CTC_IPFIX_REASON_DEST_CHANGE:
    case CTC_IPFIX_REASON_TTL_CHANGE:
    case CTC_IPFIX_REASON_TC_MARK:
        dir = CTC_INGRESS;
        break;
    case CTC_IPFIX_REASON_JITTER_OVERFLOW:
    case CTC_IPFIX_REASON_LATENCY_OVERFLOW:
        dir = CTC_EGRESS;
        break;
    case CTC_IPFIX_REASON_HASH_CONFLICT:
    case CTC_IPFIX_REASON_DUMP:
        return CTC_E_NOT_SUPPORT;
    default:
        break;
    }
    if(p_dir)
    {
        *p_dir = dir;
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_get_drop_dir(uint16 reason_id, uint8* p_dir)
{
    uint8 dir = 0;

    switch (reason_id)
    {
    case CTC_DROP_NONE                           :
    case CTC_DROP_LPBK_ERR                       :
    case CTC_DROP_PARSER_ERR                     :
    case CTC_DROP_ICMP_ERR                       :
    case CTC_DROP_TTL_CHK                        :
    case CTC_DROP_SD_CHK                         :
    case CTC_DROP_FWD_ERR                        :
    case CTC_DROP_VLAN_FILTER                    :
    case CTC_DROP_IP_CHK                         :
    case CTC_DROP_STP_CHK                        :
    case CTC_DROP_POLICING                       :
    case CTC_DROP_ISOLATE_CHK                    :
    case CTC_DROP_PKT_ERR                        :
    case CTC_DROP_HW_ERR                         :
    case CTC_DROP_SCL_DENY                       :
    case CTC_DROP_ACL_DENY                       :
    case CTC_DROP_OAM                            :
    case CTC_DROP_DOT1AE                         :
    case CTC_DROP_MAX                            :
        dir = CTC_BOTH_DIRECTION;
        break;
    case CTC_DROP_EXCP                           :
    case CTC_DROP_RECEIVE_DISABLE                :
    case CTC_DROP_SECURITY_CHK                   :
    case CTC_DROP_PORT_MAC_CHK                   :
    case CTC_DROP_STK_CHK                        :
    case CTC_DROP_BPE_PORT_ERR                   :
    case CTC_DROP_IP_SRC_GUARD                   :
    case CTC_DROP_LAG_EMPTY                      :
    case CTC_DROP_APS                            :
    case CTC_DROP_PTP                            :
    case CTC_DROP_TRILL                          :
    case CTC_DROP_MIMICRY                        :
    case CTC_DROP_ARP_OR_DHCP_ERR                :
    case CTC_DROP_VXLAN_CHK                      :
    case CTC_DROP_TUNNEL_CHK                     :
    case CTC_DROP_MPLS_CHK                       :
        dir = CTC_INGRESS;
        break;
    case CTC_DROP_TRANSIT_DISABLE                :
    case CTC_DROP_VPLS                           :
    case CTC_DROP_ARP_MISS                       :
    case CTC_DROP_MIRROR                         :
    case CTC_DROP_BFD                            :
    case CTC_DROP_PON                            :
    case CTC_DROP_MTU_CHK                        :
    case CTC_DROP_PLD_OP_ERR                     :
    case CTC_DROP_LATENCY                        :
    case CTC_DROP_EDIT_ERR                       :
    case CTC_DROP_CHKSUM_ERR                     :
    case CTC_DROP_QUEUE                         :
        dir = CTC_EGRESS;
        break;
    case CTC_DROP_TRAFFIC_MANAGER                :
    case CTC_DROP_NET_TX                         :
    case CTC_DROP_NET_RX                         :
        return CTC_E_NOT_SUPPORT;
    default:
        break;
    }
    if(p_dir)
    {
        *p_dir = dir;
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_get_drop_init_value(uint8 dir, uint32* p_drop_init_value)
{
    uint32 drop_init_value[2]={0,0};
    /* both */
    CTC_BMP_SET(drop_init_value,CTC_DROP_NONE);
    CTC_BMP_SET(drop_init_value,CTC_DROP_LPBK_ERR);
    CTC_BMP_SET(drop_init_value,CTC_DROP_PARSER_ERR);
    CTC_BMP_SET(drop_init_value,CTC_DROP_ICMP_ERR);
    CTC_BMP_SET(drop_init_value,CTC_DROP_TTL_CHK);
    CTC_BMP_SET(drop_init_value,CTC_DROP_SD_CHK);
    CTC_BMP_SET(drop_init_value,CTC_DROP_FWD_ERR);
    CTC_BMP_SET(drop_init_value,CTC_DROP_VLAN_FILTER);
    CTC_BMP_SET(drop_init_value,CTC_DROP_IP_CHK);
    CTC_BMP_SET(drop_init_value,CTC_DROP_STP_CHK);
    CTC_BMP_SET(drop_init_value,CTC_DROP_POLICING);
    CTC_BMP_SET(drop_init_value,CTC_DROP_ISOLATE_CHK);
    CTC_BMP_SET(drop_init_value,CTC_DROP_PKT_ERR);
    CTC_BMP_SET(drop_init_value,CTC_DROP_HW_ERR);
    CTC_BMP_SET(drop_init_value,CTC_DROP_SCL_DENY);
    CTC_BMP_SET(drop_init_value,CTC_DROP_ACL_DENY);
    CTC_BMP_SET(drop_init_value,CTC_DROP_OAM);
    CTC_BMP_SET(drop_init_value,CTC_DROP_DOT1AE);
    if(CTC_INGRESS==dir)
    {
        CTC_BMP_SET(drop_init_value,CTC_DROP_EXCP);
        CTC_BMP_SET(drop_init_value,CTC_DROP_RECEIVE_DISABLE);
        CTC_BMP_SET(drop_init_value,CTC_DROP_SECURITY_CHK);
        CTC_BMP_SET(drop_init_value,CTC_DROP_PORT_MAC_CHK);
        CTC_BMP_SET(drop_init_value,CTC_DROP_STK_CHK);
        CTC_BMP_SET(drop_init_value,CTC_DROP_BPE_PORT_ERR);
        CTC_BMP_SET(drop_init_value,CTC_DROP_IP_SRC_GUARD);
        CTC_BMP_SET(drop_init_value,CTC_DROP_LAG_EMPTY);
        CTC_BMP_SET(drop_init_value,CTC_DROP_APS);
        CTC_BMP_SET(drop_init_value,CTC_DROP_PTP);
        CTC_BMP_SET(drop_init_value,CTC_DROP_TRILL);
        CTC_BMP_SET(drop_init_value,CTC_DROP_MIMICRY);
        CTC_BMP_SET(drop_init_value,CTC_DROP_ARP_OR_DHCP_ERR);
        CTC_BMP_SET(drop_init_value,CTC_DROP_VXLAN_CHK);
        CTC_BMP_SET(drop_init_value,CTC_DROP_TUNNEL_CHK);
        CTC_BMP_SET(drop_init_value,CTC_DROP_MPLS_CHK);
    }
    else
    {
        CTC_BMP_SET(drop_init_value,CTC_DROP_TRANSIT_DISABLE);
        CTC_BMP_SET(drop_init_value,CTC_DROP_VPLS);
        CTC_BMP_SET(drop_init_value,CTC_DROP_ARP_MISS);
        CTC_BMP_SET(drop_init_value,CTC_DROP_MIRROR);
        CTC_BMP_SET(drop_init_value,CTC_DROP_BFD);
        CTC_BMP_SET(drop_init_value,CTC_DROP_PON);
        CTC_BMP_SET(drop_init_value,CTC_DROP_MTU_CHK);
        CTC_BMP_SET(drop_init_value,CTC_DROP_PLD_OP_ERR);
        CTC_BMP_SET(drop_init_value,CTC_DROP_LATENCY);
        CTC_BMP_SET(drop_init_value,CTC_DROP_EDIT_ERR);
        CTC_BMP_SET(drop_init_value,CTC_DROP_CHKSUM_ERR);
        CTC_BMP_SET(drop_init_value,CTC_DROP_QUEUE);
    }
    CTC_BMP_SET(drop_init_value, CTC_DROP_MAX);
    if(p_drop_init_value)
    {
        sal_memcpy(p_drop_init_value, drop_init_value, sizeof(drop_init_value));
    }
    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_init_register(uint8 lchip, void* p_global_cfg)
{
    uint16 loop_i = 0;
    uint32 entry_num = 0;
    uint32 cmd = 0;
    uint32 value_a = 0;
    uint32 max_phy_ptr = 0;
    uint32 ipfixftm = 0;
#ifndef EMULATION_ENV
    uint32 ctc_export_interval = 100; /*default value: 100ms */
    uint32 sys_export_interval = 0;
#endif
    uint32 sys_suppress_reason_bmp = 0;
    uint32 flow_change_cnt_mask[8] = {0};
    uint32 drop_init_value0[2]={0,0};
    uint32 drop_init_value1[2]={0,0};
    ctc_ipfix_global_cfg_t ipfix_cfg;
    drv_work_platform_type_t platform_type;
    IpfixHashLookupCtl_m ipfix_hash;
    IpeFwdFlowHashCtl_m  ipfix_flow_hash;
    IpfixEngineCtl0_m      ipfix_ctl0;
    IpfixEngineCtl1_m      ipfix_ctl1;
    IpePreLookupFlowCtl_m lookup_ctl;
    IpfixFlushTimerCtl_m flush_tim_ctl;
    IpfixAgingTimerCtl_m aging_tim_ctl;
    EpeHeaderEditBypassCfg_m epe_hdr_cfg;

    sal_memset(&ipfix_cfg, 0, sizeof(ctc_ipfix_global_cfg_t));
    sal_memset(&ipfix_hash, 0, sizeof(IpfixHashLookupCtl_m));
    sal_memset(&ipfix_flow_hash, 0, sizeof(ipfix_flow_hash));
    sal_memset(&ipfix_ctl0, 0, sizeof(IpfixEngineCtl0_m));
    sal_memset(&ipfix_ctl1, 0, sizeof(IpfixEngineCtl1_m));
    sal_memset(&lookup_ctl, 0, sizeof(IpePreLookupFlowCtl_m));
    sal_memset(&flush_tim_ctl, 0, sizeof(flush_tim_ctl));
    sal_memset(&aging_tim_ctl, 0, sizeof(aging_tim_ctl));
    /* flowChangeCnt (0, 5, 4)  4bit  valid(0,0,1) 1bit*/
    flow_change_cnt_mask[0]=(SYS_GET_CHIP_VERSION == SYS_CHIP_SUB_VERSION_A)? 0x1E1: 0x1E0;
    drv_get_platform_type(lchip, &platform_type);

    /*p_global_cfg is NULL, using default config, else using user define */
    sal_memcpy(&ipfix_cfg, p_global_cfg, sizeof(ctc_ipfix_global_cfg_t));

    cmd = DRV_IOR(IpfixEngineCtl1_t, DRV_ENTRY_FLAG);   /* read first, due to spanOnDropQueueDiscardType init in register before this */
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_ctl1));

    SetIpfixEngineCtl0(V, bypassUpdateOp_f, &ipfix_ctl0, 0);
    SetIpfixEngineCtl0(V, enableRecordMissPktCnt_f , &ipfix_ctl0, 1);
    SetIpfixEngineCtl0(V, ttlChangeUpdateLastTtlField_f, &ipfix_ctl0, 1); /* for update ttl*/
    SetIpfixEngineCtl0(V, bcastPktDestIsVlanId_f, &ipfix_ctl0, 1);        /* default use vsiid, not mcastgroupid */
    SetIpfixEngineCtl0(V, dropCheckEnMask_f, &ipfix_ctl0, 0x3);           /* for CTC_IPFIX_REASON_TC_MARK*/
    SetIpfixEngineCtl0(V, dropFlagMask_f, &ipfix_ctl0, 0x3);              /* for CTC_IPFIX_REASON_TC_MARK*/
    SetIpfixEngineCtl0(V, firstDropPktTriggerEventEn_f, &ipfix_ctl0, 1);   /* for CTC_IPFIX_REASON_DROP_REASON_CHANGE*/
    SetIpfixEngineCtl1(V, firstDropPktTriggerEventEn_f, &ipfix_ctl1, 1);
    SetIpfixEngineCtl1(V, spanOnDropQueueDiscardType_f, &ipfix_ctl1, 0x3b);   /*EPEDISCARDTYPE_SPAN_ONDROP_RSV_QUID*/

    cmd = DRV_IOR( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_flow_hash));
    SetIpeFwdFlowHashCtl(V, ipfixDestUseApsGroupId_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, ipfixDestUseEcmpGroupId_f , &ipfix_flow_hash,0);
    SetIpeFwdFlowHashCtl(V, ipfixHashBackToL3V6Type_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL2Type_f , &ipfix_flow_hash, 0x3);
    SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL3Type_f , &ipfix_flow_hash, 1);

    /*set merge global control */
    cmd = DRV_IOR( IpePreLookupFlowCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &lookup_ctl));
    SetIpePreLookupFlowCtl(V, flowVxlanFlowKeyL4UseOuter_f, &lookup_ctl, 1);
    SetIpePreLookupFlowCtl(V, flowGreFlowKeyL4UseOuter_f  , &lookup_ctl, 1);

    /* ipfix mirror*/
    value_a = 1;
    cmd = DRV_IOW( IpeFwdCtl_t, IpeFwdCtl_ipfixMirrorPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value_a));

    /*0: srv6(flex edit); 2: ipfix; 3: invalid*/
    value_a = 2;
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_glbIntOrSrOrIpfixMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value_a));
    cmd = DRV_IOW(EpeHdrAdjustCtl_t, EpeHdrAdjustCtl_glbIntOrSrOrIpfixMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value_a));
    cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_glbIntOrSrOrIpfixMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value_a));

    /* when EpeHeaderEditCtl.glbIntOrSrOrIpfixMode is 2, packet header tail cannot carry dest-port*/
    cmd = DRV_IOR(EpeHeaderEditBypassCfg_t,DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_hdr_cfg));
    SetEpeHeaderEditBypassCfg(V, tailContainDestPort_f, &epe_hdr_cfg, 0);
    cmd = DRV_IOW(EpeHeaderEditBypassCfg_t,DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_hdr_cfg));
    sys_usw_packet_tx_set_property(lchip, SYS_PKT_TX_TYPE_HDR_WITH_DSTPORT, 0, 0);

    /* default record ecn, compatible for TM DT2 */
    sys_usw_ftm_query_table_entry_num(lchip,DsIpfixConfig0_t,&entry_num);
    CTC_BIT_SET(sys_suppress_reason_bmp, _sys_usw_ipfix_mapping_ctc_to_sys_export_reason(lchip, CTC_IPFIX_REASON_TC_MARK));
    _sys_tmm_ipfix_get_drop_init_value(CTC_INGRESS, drop_init_value0);
    _sys_tmm_ipfix_get_drop_init_value(CTC_EGRESS, drop_init_value1);
    for(loop_i=0; loop_i<entry_num; loop_i++)
    {
        cmd = DRV_IOW(DsIpfixConfig0_t, DsIpfixConfig0_disableCaptureEvent_f);      /* default record ecn, compatible for TM DT2 */
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_i, cmd, &sys_suppress_reason_bmp));

        cmd = DRV_IOW(DsIpfixConfig0_t, DsIpfixConfig0_discardVectorExportBmp_f);      /* compatible for CTC_IPFIX_DATA_DROP_DETECTED*/
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_i, cmd, drop_init_value0));
        cmd = DRV_IOW(DsIpfixConfig1_t, DsIpfixConfig1_discardVectorExportBmp_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_i, cmd, drop_init_value1));
    }

    /* enable256kmode */
    cmd = DRV_IOR( IpfixHashLookupCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_hash));

    if(SYS_IPFIX_SHORT_MODE_NUM == SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX))
    {
        SetIpfixHashLookupCtl(V, enable256kFlowMode_f, &ipfix_hash, 1);
        SetIpfixEngineCtl0(V, enable256kFlowMode_f , &ipfix_ctl0, 1);
        SetIpfixEngineCtl1(V, enable256kFlowMode_f , &ipfix_ctl1, 1);
        SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL3Type_f , &ipfix_flow_hash, 1);
        SetIpePreLookupFlowCtl(V, flowGreFlowKeyL4UseOuter_f  , &lookup_ctl, 1);
        SetIpePreLookupFlowCtl(V, flowCapwapFlowKeyL4UseOuter_f,&lookup_ctl, 1);
        p_usw_ipfix_master[lchip]->short_mode = 1;
    }
     /*IPFix hash ctl*/
    ipfixftm=SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX);

    SetIpfixHashLookupCtl(V, ipfixLevel0HashEn_f, &ipfix_hash, 1);
    SetIpfixHashLookupCtl(V, ipfixLevel1HashEn_f, &ipfix_hash, (ipfixftm > SYS_IPFIX_HASH_BUCKET_NUM));
    SetIpfixHashLookupCtl(V, ipfixLevel2HashEn_f, &ipfix_hash, (ipfixftm > SYS_IPFIX_HASH_BUCKET_NUM*2));
    SetIpfixHashLookupCtl(V, ipfixLevel3HashEn_f, &ipfix_hash, (ipfixftm > SYS_IPFIX_HASH_BUCKET_NUM*3));

   /* aging and export timer */
    cmd = DRV_IOR(IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &aging_tim_ctl));
    SetIpfixAgingTimerCtl(V, agingUpdEn_f, &aging_tim_ctl, 1);  /* Timer Enable */
    /* flowChangeCnt (0, 5, 4)  4bit */
    SetIpfixAgingTimerCtl(A, removeIngressAdMask_f , &aging_tim_ctl, flow_change_cnt_mask);
    SetIpfixAgingTimerCtl(A, removeEgressAdMask_f , &aging_tim_ctl, flow_change_cnt_mask);
    CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_max_phy_ptr(lchip, &max_phy_ptr));
    SetIpfixAgingTimerCtl(V, agingMaxPtr_f , &aging_tim_ctl, max_phy_ptr);
    SetIpfixAgingTimerCtl(V, agingMinPtr_f , &aging_tim_ctl, 0);
    SetIpfixAgingTimerCtl(V, agingPhyMaxPtr_f , &aging_tim_ctl, max_phy_ptr);
#ifndef EMULATION_ENV
    CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_interval(lchip, 0, &ctc_export_interval, &sys_export_interval)); /*default value: 100ms */
    SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_tim_ctl, sys_export_interval);
#endif


    /* flush and dump timer */
    cmd = DRV_IOR(IpfixFlushTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &flush_tim_ctl));
    SetIpfixFlushTimerCtl(V, forceFlushReasonExport_f , &flush_tim_ctl, 1);
    SetIpfixFlushTimerCtl(V, operationOneRound_f , &flush_tim_ctl, 1);
    SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, flow_change_cnt_mask);
    SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, flow_change_cnt_mask);
    CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_max_phy_ptr(lchip, &max_phy_ptr));
    SetIpfixFlushTimerCtl(V, maxPtr_f , &flush_tim_ctl, max_phy_ptr);
    SetIpfixFlushTimerCtl(V, minPtr_f , &flush_tim_ctl, 0);
    SetIpfixFlushTimerCtl(V, phyMaxPtr_f , &flush_tim_ctl, max_phy_ptr);
    SetIpfixFlushTimerCtl(V, flushInterval_f, &flush_tim_ctl, 1000);/*default 1000 ticks trigger dump 480 bits*/
    if (platform_type == HW_PLATFORM)
    {
        #ifdef EMULATION_ENV
        SetIpfixFlushTimerCtl(V, flushInterval_f, &flush_tim_ctl, 100);    /* Emulation  special process due to fre down */
        #endif
    }

    cmd = DRV_IOW( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_flow_hash));

    cmd = DRV_IOW( IpfixHashLookupCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_hash));

    cmd = DRV_IOW( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_ctl0));

    cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipfix_ctl1));

    cmd = DRV_IOW( IpePreLookupFlowCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &lookup_ctl));

    cmd = DRV_IOW( IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &aging_tim_ctl));

    cmd = DRV_IOW( IpfixFlushTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &flush_tim_ctl));

    value_a = (SYS_IPFIX_SHORT_MODE_NUM == ipfixftm )? 1 : 0;
    CTC_ERROR_RETURN(sys_usw_ipfix_set_short_key_mode(lchip, value_a));
    CTC_ERROR_RETURN(_sys_tmm_ipfix_drop_classid_spool_init(lchip));
    CTC_ERROR_RETURN(_sys_tmm_ipfix_init_drop_reason(lchip));

    CTC_ERROR_RETURN(sys_tmm_ipfix_set_global_cfg(lchip,p_global_cfg));

    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_set_property(uint8 lchip, void* cfg)
{
    uint32 value = 0;
    uint32 cmd = 0;
    uint32 ad_mask[8] = {0};
    ctc_ipfix_bulk_op_t* p_bulk_op = NULL;
    IpfixFlushTimerCtl_m flush_tim_ctl;
    ctc_ipfix_property_t *p_ipfix_prop = (ctc_ipfix_property_t*)cfg;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(cfg);
    sal_memset(&flush_tim_ctl, 0, sizeof(flush_tim_ctl));

    switch(p_ipfix_prop->type)
    {
    case CTC_IPFIX_PROP_BULK_OP:
        p_bulk_op = (ctc_ipfix_bulk_op_t*)p_ipfix_prop->value;
        if(0 == p_bulk_op->p_param->entry_num)
        {
            p_bulk_op->p_param = NULL;
        }
        if(p_bulk_op->p_param&&((0!=p_bulk_op->p_param->start_index%4)||(0!=p_bulk_op->p_param->entry_num%4)))
        {/* start_index and entry_num are both multiple of 4, start_index based on 120bits */
            return CTC_E_INVALID_PARAM;
        }
        cmd = DRV_IOR(IpfixFlushTimerCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));
        if(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_BY_PROF))
        {
            SetIpfixFlushTimerCtl(V, operationBasedOnProfileIdMatch_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, operationProfileId_f, &flush_tim_ctl, p_bulk_op->prof_id);
        }
        else
        {
            SetIpfixFlushTimerCtl(V, operationBasedOnProfileIdMatch_f, &flush_tim_ctl, 0);
        }
        if(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)&& !CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN))
        {/* only dump */
            SetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, disableFlushFlowToDma_f, &flush_tim_ctl, 0);
            /* revise for rtl bug */
            sal_memset(ad_mask, 0xff, sizeof(ad_mask));
            SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, ad_mask);
            SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, ad_mask);
        }
        else if(!CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)&& CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN))
        {/* only flush */
            SetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, disableFlushFlowToDma_f, &flush_tim_ctl, 0);
            /* revise for rtl bug */
            sal_memset(ad_mask, 0, sizeof(ad_mask));
            ad_mask[0] = 0x1E0;/* keep flowChangeCnt value when remove entry */
            SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, ad_mask);
            SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, ad_mask);
        }
        else if(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)&& CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN))
        {/* dump and flush */
            SetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, disableFlushFlowToDma_f, &flush_tim_ctl, 0);
            /* revise for rtl bug */
            sal_memset(ad_mask, 0, sizeof(ad_mask));
            ad_mask[0] = 0x1E0;/* keep flowChangeCnt value when remove entry */
            SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, ad_mask);
            SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, ad_mask);
        }
        if(p_bulk_op->p_param &&(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)
            && !CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN)))  /* dump in specific section */
        {
            SetIpfixFlushTimerCtl(V, minPtr_f, &flush_tim_ctl, p_bulk_op->p_param->start_index/4);
            p_bulk_op->p_param->next_traverse_index = p_bulk_op->p_param->start_index + p_bulk_op->p_param->entry_num;
            if( p_bulk_op->p_param->next_traverse_index >= SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX))
            {
                p_bulk_op->p_param->is_end = 1;
            }
            if(!p_bulk_op->p_param->is_end)
            {
                SetIpfixFlushTimerCtl(V, phyMaxPtr_f, &flush_tim_ctl, p_bulk_op->p_param->next_traverse_index/4);
                SetIpfixFlushTimerCtl(V, maxPtr_f, &flush_tim_ctl, p_bulk_op->p_param->next_traverse_index/4);
            }
            else
            {
                SetIpfixFlushTimerCtl(V, phyMaxPtr_f, &flush_tim_ctl, 0xFFFF);
                SetIpfixFlushTimerCtl(V, maxPtr_f, &flush_tim_ctl, 0xFFFF);
            }
        }
        else
        {
            SetIpfixFlushTimerCtl(V, minPtr_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, phyMaxPtr_f, &flush_tim_ctl, 0xFFFF);
            SetIpfixFlushTimerCtl(V, maxPtr_f, &flush_tim_ctl, 0xFFFF);
        }

        cmd = DRV_IOW( IpfixFlushTimerCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));

        value = 0;
        cmd = DRV_IOW(IpfixFlushMissDmaFifoFullCount_t, IpfixFlushMissDmaFifoFullCount_count1_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
        value = 1;
        cmd = DRV_IOW(IpfixFlushTimerUpdateCtl_t, IpfixFlushTimerUpdateCtl_updEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
        break;
    }
    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_get_property(uint8 lchip, void* cfg)
{
    uint32 cmd = 0;
    ctc_ipfix_bulk_op_t* p_bulk_op = NULL;
    ctc_ipfix_bulk_op_miss_t* p_bulk_op_miss = NULL;
    IpfixFlushTimerCtl_m flush_tim_ctl;
    IpfixFlushTimerUpdateCtl_m flush_tim_up_ctl;
    IpfixFlushMissDmaFifoFullCount_m dump_miss_cnt;
    ctc_ipfix_property_t *p_ipfix_prop = (ctc_ipfix_property_t*)cfg;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(cfg);
    sal_memset(&flush_tim_ctl, 0, sizeof(flush_tim_ctl));
    sal_memset(&flush_tim_up_ctl, 0, sizeof(flush_tim_up_ctl));
    sal_memset(&dump_miss_cnt, 0, sizeof(dump_miss_cnt));

    switch(p_ipfix_prop->type)
    {
        case CTC_IPFIX_PROP_BULK_OP:
            p_bulk_op = (ctc_ipfix_bulk_op_t*)p_ipfix_prop->value;
            cmd = DRV_IOR(IpfixFlushTimerCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl);
            p_bulk_op->prof_id = GetIpfixFlushTimerCtl(V, operationProfileId_f, &flush_tim_ctl);
            if(GetIpfixFlushTimerCtl(V, operationBasedOnProfileIdMatch_f, &flush_tim_ctl))
            {
                CTC_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_BY_PROF);
            }
            if((0==GetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl)) && (0==GetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl)))
            {
                CTC_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN);
            }
            if(GetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl) && GetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl))
            {
                CTC_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN);
            }
            break;
        case CTC_IPFIX_PROP_BULK_MISS:
            p_bulk_op_miss = (ctc_ipfix_bulk_op_miss_t*)p_ipfix_prop->value;
            cmd = DRV_IOR(IpfixFlushMissDmaFifoFullCount_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &dump_miss_cnt);
            p_bulk_op_miss->miss_cnt = GetIpfixFlushMissDmaFifoFullCount(V, count1_f, &dump_miss_cnt);
            cmd = DRV_IOR(IpfixFlushTimerUpdateCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_up_ctl);
            p_bulk_op_miss->one_round_done = !GetIpfixFlushTimerUpdateCtl(V, updEn_f, &flush_tim_up_ctl);
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}


int32
sys_tmm_ipfix_set_global_cfg(uint8 lchip, void* cfg)
{
    uint16 loop_i = 0;
    uint32 cmd = 0;
    uint32 byte_cnt[2] = {0};
    uint32 pkt_cnt = 0;
    uint32 value_a = 0;
    uint32 common_drop_reason = CTC_DROP_MAX;
    IpfixEngineCtl0_m    ipfix_ctl0;
    IpfixEngineCtl1_m    ipfix_ctl1;
    DsIpfixConfig0_m  ipfix_cfg0;
    DsIpfixConfig1_m  ipfix_cfg1;
    IpeFwdFlowHashCtl_m ipe_fwd_flow_ctl;
    IpeFwdCtl_m  ipe_fwd_ctl;
    ctc_ipfix_global_cfg_t *ipfix_cfg = (ctc_ipfix_global_cfg_t*)cfg;
    void *user_info = NULL; /*use for ctc_ipfix_data_t export */

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    ipfix_cfg->drop_pkt_cnt = (ipfix_cfg->drop_pkt_cnt == 0) ? 0x200 : ipfix_cfg->drop_pkt_cnt;
    CTC_MAX_VALUE_CHECK(ipfix_cfg->drop_pkt_cnt, 0x3FF);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->jitter_thrd, 0xFFFF);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->jitter_ewma_weight, 0x7);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->latency_ewma_weight, 0x7);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->max_export_entry_num,SYS_IPFIX_MAX_EXPORT_ENTRY_NUM);

    if (ipfix_cfg->ignore_drop_reason)
    {
        for (loop_i = 0; loop_i < TABLE_MAX_INDEX(lchip, DsIpfixConfig0_t); loop_i++)
        {
            cmd = DRV_IOR(DsIpfixConfig0_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &ipfix_cfg0);
            cmd = DRV_IOR(DsIpfixConfig1_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &ipfix_cfg1);
            if (GetDsIpfixConfig0(V, recordDiscardVectorEn_f, &ipfix_cfg0) || GetDsIpfixConfig1(V, recordDiscardVectorEn_f, &ipfix_cfg1))
            {
                return CTC_E_INVALID_PARAM;
            }
        }
    }

    pkt_cnt = (ipfix_cfg->pkt_cnt == 0) ? 0:(ipfix_cfg->pkt_cnt - 1);
    sal_memset(&ipfix_ctl0, 0, sizeof(IpfixEngineCtl0_m));
    sal_memset(&ipfix_ctl1, 0, sizeof(IpfixEngineCtl1_m));

    /* IpeFwdCtl */
    value_a = !!ipfix_cfg->conflict_export;
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_ipfixConflictPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    /* Queue drop stats */
    value_a = !!ipfix_cfg->queue_drop_en;
    if(DRV_IS_AT(lchip) && SYS_PP_BASE(lchip) == lchip && CTC_WB_STATUS(lchip) != CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_set_monitor_drop_discard_enable(lchip, value_a));
    }
    else
    {
        cmd = DRV_IOW(EpeHdrAdjSpanCtl_t, EpeHdrAdjSpanCtl_spanOnDropDiscardEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value_a));
    }
    /* IpfixEngineCtl0 ; IpfixEngineCtl1 */
    cmd = DRV_IOR( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl0));
    cmd = DRV_IOR( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl1));

    byte_cnt[0] = (ipfix_cfg->bytes_cnt) & 0xffffffff;
    byte_cnt[1] = (ipfix_cfg->bytes_cnt >> 32) & 0xffffffff;
    SetIpfixEngineCtl0(A, byteCntWraparoundThre_f, &ipfix_ctl0, byte_cnt);
    SetIpfixEngineCtl1(A, byteCntWraparoundThre_f, &ipfix_ctl1, byte_cnt);

    SetIpfixEngineCtl0(V, pktCntWraparoundThre_f , &ipfix_ctl0, pkt_cnt);
    SetIpfixEngineCtl1(V, pktCntWraparoundThre_f , &ipfix_ctl1, pkt_cnt);

    SetIpfixEngineCtl0(V, ignorTcpClose_f , &ipfix_ctl0, ((ipfix_cfg->tcp_end_detect_en)?0:1));

    SetIpfixEngineCtl0(V, tsWrapAroundThre_f , &ipfix_ctl0, ipfix_cfg->times_interval);  /*granularity is 1ms*/
    SetIpfixEngineCtl0(V, isCpuSetFlowKeyMode_f , &ipfix_ctl0, ipfix_cfg->sw_learning_en);
    SetIpfixEngineCtl0(V, unknownPktDestIsVlanId_f, &ipfix_ctl0, ipfix_cfg->unkown_pkt_dest_type);
    SetIpfixEngineCtl0(V, newFlowExportEn_f  , &ipfix_ctl0, !!ipfix_cfg->new_flow_export_en);

    SetIpfixEngineCtl1(V, ignorTcpClose_f , &ipfix_ctl1, ((ipfix_cfg->tcp_end_detect_en)?0:1));
    SetIpfixEngineCtl1(V, isCpuSetFlowKeyMode_f , &ipfix_ctl1, ipfix_cfg->sw_learning_en);
    SetIpfixEngineCtl1(V, newFlowExportEn_f  , &ipfix_ctl1, !!ipfix_cfg->new_flow_export_en);

    if(ipfix_cfg->threshold)
    {
        SetIpfixEngineCtl0(V, flowUseageIntEnable_f, &ipfix_ctl0, 0x3);
        SetIpfixEngineCtl1(V, flowUseageIntEnable_f, &ipfix_ctl1, 0x3);
    }
    else
    {
        SetIpfixEngineCtl0(V, flowUseageIntEnable_f, &ipfix_ctl0, 0);
        SetIpfixEngineCtl1(V, flowUseageIntEnable_f, &ipfix_ctl1, 0);
    }
    SetIpfixEngineCtl0(V, flowCountThreshold_f, &ipfix_ctl0, ipfix_cfg->threshold);
    SetIpfixEngineCtl1(V, flowCountThreshold_f, &ipfix_ctl1, ipfix_cfg->threshold);
    SetIpfixEngineCtl0(V, ignorSeqIdIsZeroCheck_f, &ipfix_ctl0, value_a);
    SetIpfixEngineCtl0(V, dropPktCntWrapAroundThrd0_f, &ipfix_ctl0, ipfix_cfg->drop_pkt_cnt);
    SetIpfixEngineCtl0(V, dropPktCntWrapAroundThrd1_f, &ipfix_ctl0, ipfix_cfg->drop_pkt_cnt);
    SetIpfixEngineCtl1(V, dropPktCntWrapAroundThrd0_f, &ipfix_ctl1, ipfix_cfg->drop_pkt_cnt);
    SetIpfixEngineCtl1(V, dropPktCntWrapAroundThrd1_f, &ipfix_ctl1, ipfix_cfg->drop_pkt_cnt);

    SetIpfixEngineCtl1(V, maxJitterExportThreCheckEn_f, &ipfix_ctl1, (0!=ipfix_cfg->jitter_thrd));
    SetIpfixEngineCtl1(V, maxLatencyExportThreCheckEn_f, &ipfix_ctl1, (0!=ipfix_cfg->latency_thrd));

    SetIpfixEngineCtl1(V, maxJitterExportThreshold_f, &ipfix_ctl1, ipfix_cfg->jitter_thrd);
    SetIpfixEngineCtl1(V, maxLatencyExportThreshold_f, &ipfix_ctl1,ipfix_cfg->latency_thrd);
    SetIpfixEngineCtl1(V, avgJitterEwmaWeight_f, &ipfix_ctl1, ipfix_cfg->jitter_ewma_weight);
    SetIpfixEngineCtl1(V, avgLatencyEwmaWeight_f, &ipfix_ctl1, ipfix_cfg->latency_ewma_weight);

    cmd = DRV_IOW( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl0));
    cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl1));

    /*0: srv6(flex edit); 2: ipfix; 3: invalid*/
    if(ipfix_cfg->egs_ipfix_disable && DRV_FROM_AT(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        value_a = ipfix_cfg->egs_ipfix_disable ? 0 : 2;
        cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_glbIntOrSrOrIpfixMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
        cmd = DRV_IOW(EpeHdrAdjustCtl_t, EpeHdrAdjustCtl_glbIntOrSrOrIpfixMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
        cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_glbIntOrSrOrIpfixMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    }
    if(0 == ipfix_cfg->conflict_cnt)
    {
        cmd = DRV_IOW(IpfixMissPktCounter_t, IpfixMissPktCounter_missPktCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_cfg->conflict_cnt));
        cmd = DRV_IOW( IpfixMissPktCounter0_t, IpfixMissPktCounter0_missPktCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_cfg->conflict_cnt));
        cmd = DRV_IOW( IpfixMissPktCounter1_t, IpfixMissPktCounter1_missPktCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_cfg->conflict_cnt));
    }
    CTC_ERROR_RETURN(_sys_tmm_ipfix_set_aging_export_timer_interval(lchip, cfg));
    cmd = DRV_IOW(IpeFwdFlowHashCtl_t, IpeFwdFlowHashCtl_ipfixDestUseLagId_f);
    value_a = ipfix_cfg->dest_port_type?0:1;
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    
    if(ipfix_cfg->ignore_drop_reason)
    {
        for(loop_i=0; loop_i<TABLE_MAX_INDEX(lchip, IpfixEngineDiscardMapCtl0_t); loop_i++)
        {
            cmd = DRV_IOW(IpfixEngineDiscardMapCtl0_t, IpfixEngineDiscardMapCtl0_discardTypeMap_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &common_drop_reason));
            cmd = DRV_IOW(IpfixEngineDiscardMapCtl1_t, IpfixEngineDiscardMapCtl1_discardTypeMap_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &common_drop_reason));
        }
        p_usw_ipfix_master[lchip]->ignore_drop_reason = 1;
    }
    else
    {
        CTC_ERROR_RETURN(_sys_tmm_ipfix_init_drop_reason(lchip));
        p_usw_ipfix_master[lchip]->ignore_drop_reason = 0;
    }
    cmd = DRV_IOR(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));
    SetIpeFwdFlowHashCtl(V, mirrorPktEnableIpfix_f, &ipe_fwd_flow_ctl, ipfix_cfg->mirror_pkt_enable ? 1:0);
    cmd = DRV_IOW(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));

    cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_ctl));
    if (DRV_FROM_AT(lchip))
    {
        SetIpeFwdCtl(V, fromCflexSupportIpfix_f, &ipe_fwd_ctl, 1);
    }
    if(ipfix_cfg->mirror_pkt_enable)
    {
        SetIpeFwdCtl(V, logOnSpanPkt_f, &ipe_fwd_ctl, 1<<12|1<<11);/*just for ipfixConflictPktLogEn and ipfixMirrorEn*/
    }
    else
    {
        SetIpeFwdCtl(V, logOnSpanPkt_f, &ipe_fwd_ctl, 0);
    }
    cmd = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_ctl));

    if (DRV_FROM_AT(lchip))
    {
        EpeAclQosCtl_m epe_aclqos_ctl;
        cmd = DRV_IOR(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_aclqos_ctl));
        SetEpeAclQosCtl(V, mirrorPktEnableIpfix_f, &epe_aclqos_ctl, ipfix_cfg->mirror_pkt_enable ? 1 : 0);
        cmd = DRV_IOW(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_aclqos_ctl));
    }

    value_a = ipfix_cfg->max_export_entry_num? ipfix_cfg->max_export_entry_num : 16;
    if ((p_usw_ipfix_master[SYS_PP_BASE(lchip)]->cb_buf_status == 0)&&(value_a != p_usw_ipfix_master[lchip]->max_export_entry_num) && lchip == SYS_PP_BASE(lchip))
    {
        uint32 size;
        uint32 size_tmp;
        size_tmp = DRV_FROM_AT(lchip)?((sizeof(ctc_field_key_t)*MAX_XKEY_FIELD_NUM)+(sizeof(ctc_xdata_field_t)*MAX_XDATA_FIELD_NUM)):0;
        size = (sizeof(ctc_ipfix_data_t)+ size_tmp)* value_a;
        MALLOC_ZERO(MEM_IPFIX_MODULE, user_info, size);
        if (NULL == user_info)
        {
            return CTC_E_NO_MEMORY;
        }
        mem_free(p_usw_ipfix_master[lchip]->cb_buf);
        p_usw_ipfix_master[lchip]->cb_buf = user_info;
        p_usw_ipfix_master[lchip]->max_export_entry_num = value_a;
    }
    else
    {
        p_usw_ipfix_master[lchip]->cb_buf = p_usw_ipfix_master[SYS_PP_BASE(lchip)]->cb_buf;
        p_usw_ipfix_master[lchip]->max_export_entry_num = p_usw_ipfix_master[SYS_PP_BASE(lchip)]->max_export_entry_num;
    }
    
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER, 1);
    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_get_global_cfg(uint8 lchip, void* cfg)
{
    IpfixEngineCtl0_m    ipfix_ctl0;
    IpfixEngineCtl1_m    ipfix_ctl1;
    IpeFwdCtl_m   ipe_fwd_ctl;
    EpeHdrAdjSpanCtl_m hdradj_spanctl;
    IpeFwdFlowHashCtl_m ipe_fwd_flow_ctl;

    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 byte_cnt[2] = {0};
    uint32 value = 0;
    ctc_ipfix_global_cfg_t *ipfix_cfg = (ctc_ipfix_global_cfg_t*)cfg;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&ipfix_ctl0, 0, sizeof(IpfixEngineCtl0_m));
    sal_memset(&ipfix_ctl1, 0, sizeof(IpfixEngineCtl1_m));
    sal_memset(&ipe_fwd_ctl,0,sizeof(ipe_fwd_ctl));
    sal_memset(&hdradj_spanctl,0,sizeof(hdradj_spanctl));

    SYS_IPFIX_LOCK(lchip);

    /* Queue drop stats */
    cmd = DRV_IOR(EpeHdrAdjSpanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &hdradj_spanctl), ret, error_pro);
    ipfix_cfg->queue_drop_en = GetEpeHdrAdjSpanCtl(V, spanOnDropDiscardEn_f , &hdradj_spanctl);

    ipfix_cfg->export_interval = p_usw_ipfix_master[lchip]->export_interval;
    ipfix_cfg->aging_interval = p_usw_ipfix_master[lchip]->aging_interval;

    /* IpfixEngineCtl0, IpfixEngineCtl1 */
    cmd = DRV_IOR( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl0), ret, error_pro);
    cmd = DRV_IOR( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl1), ret, error_pro);
    GetIpfixEngineCtl0(A, byteCntWraparoundThre_f, &ipfix_ctl0, byte_cnt);
    ipfix_cfg->bytes_cnt = 0;
    ipfix_cfg->bytes_cnt = byte_cnt[1];
    ipfix_cfg->bytes_cnt <<= 32;
    ipfix_cfg->bytes_cnt |= byte_cnt[0];

    ipfix_cfg->sw_learning_en = GetIpfixEngineCtl0(V, isCpuSetFlowKeyMode_f , &ipfix_ctl0);
    ipfix_cfg->pkt_cnt = GetIpfixEngineCtl0(V, pktCntWraparoundThre_f , &ipfix_ctl0)+1;
    ipfix_cfg->times_interval = GetIpfixEngineCtl0(V, tsWrapAroundThre_f, &ipfix_ctl0);  /*1s*/
    ipfix_cfg->tcp_end_detect_en = !GetIpfixEngineCtl0(V, ignorTcpClose_f, &ipfix_ctl0);
    ipfix_cfg->new_flow_export_en = GetIpfixEngineCtl0(V, newFlowExportEn_f, &ipfix_ctl0);
    ipfix_cfg->unkown_pkt_dest_type = GetIpfixEngineCtl0(V, unknownPktDestIsVlanId_f, &ipfix_ctl0);
    ipfix_cfg->threshold = GetIpfixEngineCtl0(V, flowCountThreshold_f, &ipfix_ctl0);
    ipfix_cfg->drop_pkt_cnt = GetIpfixEngineCtl1(V, dropPktCntWrapAroundThrd0_f, &ipfix_ctl1);
    ipfix_cfg->jitter_thrd = GetIpfixEngineCtl1(V, maxJitterExportThreshold_f, &ipfix_ctl1);
    ipfix_cfg->latency_thrd = GetIpfixEngineCtl1(V, maxLatencyExportThreshold_f, &ipfix_ctl1);
    ipfix_cfg->jitter_ewma_weight = GetIpfixEngineCtl1(V, avgJitterEwmaWeight_f, &ipfix_ctl1);
    ipfix_cfg->latency_ewma_weight = GetIpfixEngineCtl1(V, avgLatencyEwmaWeight_f, &ipfix_ctl1);

    cmd = DRV_IOR(IpeFwdCtl_t,DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_ctl), ret, error_pro);

    ipfix_cfg->conflict_export = (uint8)GetIpeFwdCtl(V,ipfixConflictPktLogEn_f,&ipe_fwd_ctl);

    cmd = DRV_IOR(IpfixMissPktCounter_t, IpfixMissPktCounter_missPktCount_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &(ipfix_cfg->conflict_cnt)), ret, error_pro);

    /*0: srv6; 2: ipfix; 3: invalid*/
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOR(IpeFwdCtl_t, IpeFwdCtl_glbIntOrSrOrIpfixMode_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value), ret, error_pro);
        ipfix_cfg->egs_ipfix_disable = (value == 2) ? 0 : 1;
    }
    cmd = DRV_IOR(IpeFwdFlowHashCtl_t, IpeFwdFlowHashCtl_ipfixDestUseLagId_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value), ret, error_pro);
    ipfix_cfg->dest_port_type = value ? 0:1;
    ipfix_cfg->ignore_drop_reason = p_usw_ipfix_master[lchip]->ignore_drop_reason;
    ipfix_cfg->max_export_entry_num = p_usw_ipfix_master[lchip]->max_export_entry_num;
    cmd = DRV_IOR(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl), ret, error_pro);
    ipfix_cfg->mirror_pkt_enable = GetIpeFwdFlowHashCtl(V, mirrorPktEnableIpfix_f, &ipe_fwd_flow_ctl);
error_pro:
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

int32
_sys_tmm_ipfix_set_flow_drop_classid(uint8 lchip, void* ds0, void* ds1, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint8   loop_i = 0;
    uint8   loop_j = 0;
    uint8   drop_classid_enable = 0;
    uint32  drop_classid = 0;
    int32 ret = CTC_E_NONE;
    uint32  cmd = 0;
    DsIpfixConfig0_m* p_ds0 = (DsIpfixConfig0_m*)ds0;
    DsIpfixConfig1_m* p_ds1 = (DsIpfixConfig1_m*)ds1;
    uint32 sys_drop_bmp[8] = {0};
    uint32 drop_report_bmp[2] = {0};
    uint32 drop_report_bmp_old[2] = {0};
    sys_ipfix_drop_classid_t* p_get_drop_classid = NULL;
    sys_ipfix_drop_classid_t new_drop_classid;
    sys_ipfix_drop_classid_t old_drop_classid;

    sal_memset(&new_drop_classid, 0, sizeof(new_drop_classid));
    sal_memset(&old_drop_classid, 0, sizeof(old_drop_classid));

    if(CTC_INGRESS == p_flow_cfg->dir)
    {
        /* igs ipfix drop classid spool */
        GetDsIpfixConfig0(A, discardVectorExportBmp_f, p_ds0, drop_report_bmp_old);
        drop_classid_enable = GetDsIpfixConfig0(V, recordDiscardVectorEn_f, p_ds0);
        if(drop_classid_enable)
        {
            for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)  /* first remove */
            {
                if(CTC_BMP_ISSET(drop_report_bmp_old, loop_i))
                {
                    old_drop_classid.drop_reason = loop_i;
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "igs remove old_drop_classid.drop_reason = %d\n", old_drop_classid.drop_reason);
                    ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS], &old_drop_classid, NULL);
                    if (ret)
                    {
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove igs drop classid spool error, %%ret=%d\n", ret);
                        return ret;
                    }
                }
            }
        }
        if ((0 == p_flow_cfg->drop_pkt_mode) && (p_flow_cfg->drop_report_bmp[0] || p_flow_cfg->drop_report_bmp[1]))
        {
            for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)  /* then add */
            {
                if(CTC_BMP_ISSET(p_flow_cfg->drop_report_bmp, loop_i))
                {
                    new_drop_classid.drop_reason = loop_i;
                    ret = ctc_spool_add(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS], &new_drop_classid, NULL, &p_get_drop_classid);
                    if (ret)
                    {
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "add igs drop classid spool error, %%ret=%d\n", ret);
                        goto error_proc;
                    }

                    /*write hw*/
                    drop_classid = p_get_drop_classid->index.index;
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "igs p_get_drop_classid->drop_classid = %d\n", p_get_drop_classid->index.index);

                    /* IpfixEngineDiscardMapCtl0.discardTypeMap(5,0) */
                    sal_memset(sys_drop_bmp, 0, sizeof(sys_drop_bmp));
                    sys_tmm_map_drop_reason_ctc_to_sys(loop_i, sys_drop_bmp);
                    for(loop_j=SYS_TMM_DISCARD_IPE_START; loop_j<=SYS_TMM_DISCARD_IPE_END; loop_j++)
                    {
                        /* Ipe */
                        if(CTC_BMP_ISSET(sys_drop_bmp, loop_j))
                        {
                            cmd = DRV_IOW(IpfixEngineDiscardMapCtl0_t, IpfixEngineDiscardMapCtl0_discardTypeClassId_f);
                            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_j, DRV_CMD_PP_EN(cmd), &drop_classid));
                        }
                    }
                }
            }
        }
        sal_memcpy(drop_report_bmp, p_flow_cfg->drop_report_bmp, sizeof(drop_report_bmp));
        CTC_BMP_SET(drop_report_bmp, CTC_DROP_MAX);
        SetDsIpfixConfig0(A, discardVectorExportBmp_f, p_ds0, drop_report_bmp);
    }
    else if(CTC_EGRESS == p_flow_cfg->dir)
    {
        /* egs ipfix drop classid spool */
        GetDsIpfixConfig1(A, discardVectorExportBmp_f, p_ds1, drop_report_bmp_old);
        drop_classid_enable = GetDsIpfixConfig1(V, recordDiscardVectorEn_f, p_ds1);
        if(drop_classid_enable)
        {
            for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)  /* first remove */
            {
                if(CTC_BMP_ISSET(drop_report_bmp_old, loop_i))
                {
                    old_drop_classid.drop_reason = loop_i;
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"egs remove old_drop_classid.drop_reason = %d\n", old_drop_classid.drop_reason);
                    ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS], &old_drop_classid, NULL);
                    if (ret)
                    {
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove egs drop classid spool error, %%ret=%d\n", ret);
                        return ret;
                    }
                }
            }
        }
        if ((0 == p_flow_cfg->drop_pkt_mode) && (p_flow_cfg->drop_report_bmp[0] || p_flow_cfg->drop_report_bmp[1]))
        {
            for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)   /* then add */
            {
                if(CTC_BMP_ISSET(p_flow_cfg->drop_report_bmp, loop_i))
                {
                    new_drop_classid.drop_reason = loop_i;
                    ret = ctc_spool_add(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS], &new_drop_classid, NULL, &p_get_drop_classid);
                    if (ret)
                    {
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "add egs drop classid spool error, %%ret=%d\n", ret);
                        goto error_proc;
                    }
                    /*write hw*/
                    drop_classid = p_get_drop_classid->index.index;
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "egs p_get_drop_classid->drop_classid = %d\n", p_get_drop_classid->index.index);

                    /* IpfixEngineDiscardMapCtl1.discardTypeMap(5,0) */
                    sal_memset(sys_drop_bmp, 0, sizeof(sys_drop_bmp));
                    sys_tmm_map_drop_reason_ctc_to_sys(loop_i, sys_drop_bmp);
                    for(loop_j = SYS_TMM_DISCARD_EPE_START; loop_j<=SYS_TMM_DISCARD_EPE_END; loop_j++)
                    {
                        /* Epe */
                        if(CTC_BMP_ISSET(sys_drop_bmp, loop_j))
                        {
                            cmd = DRV_IOW(IpfixEngineDiscardMapCtl1_t, IpfixEngineDiscardMapCtl1_discardTypeClassId_f);
                            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (loop_j-(SYS_TMM_DISCARD_IPE_END + 1)), DRV_CMD_PP_EN(cmd), &drop_classid));
                        }
                    }
                }
            }
        }
        sal_memcpy(drop_report_bmp, p_flow_cfg->drop_report_bmp, sizeof(drop_report_bmp));
        CTC_BMP_SET(drop_report_bmp, CTC_DROP_MAX);
        SetDsIpfixConfig1(A, discardVectorExportBmp_f, p_ds1, drop_report_bmp);
    }
    return CTC_E_NONE;
error_proc:
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove: drop_report_bmp[0]:0x%x drop_report_bmp[1]:0x%x\n",p_flow_cfg->drop_report_bmp[0],p_flow_cfg->drop_report_bmp[1]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "add: drop_report_bmp_old[0]:0x%x drop_report_bmp_old[1]:0x%x\n",drop_report_bmp_old[0],drop_report_bmp_old[1]);
    for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)
    {
        if(CTC_BMP_ISSET(p_flow_cfg->drop_report_bmp, loop_i))
        {
            old_drop_classid.drop_reason = loop_i;
            ctc_spool_remove(p_usw_ipfix_master[lchip]->drop_classid_spool[p_flow_cfg->dir], &old_drop_classid, NULL);
        }
        if(CTC_BMP_ISSET(drop_report_bmp_old, loop_i) && drop_classid_enable) /* recover last valid cfg */
        {
            new_drop_classid.drop_reason = loop_i;
            CTC_ERROR_DUMP(ctc_spool_add(p_usw_ipfix_master[lchip]->drop_classid_spool[p_flow_cfg->dir], &new_drop_classid, NULL, NULL));
        }
    }
    return ret;
}

int32
sys_tmm_ipfix_set_flow_cfg(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32  cmd = 0;
    uint32  sample_enable = 0;
    uint32  sample_profile_index = 0;
    uint8   flow_type = 0;
    uint8   dir = 0;
    uint8   loop_i = 0;
    uint32  step = 0;
    int32   ret;
    uint32 value_a = 0;
    uint32  cfg_table_id;
    uint32  sample_cfg_table_id;
    uint32 sys_suppress_reason_bmp = 0;
    uint32 sys_deny_export_reason_bmp = 0;
    DsIpfixConfig0_m  ipfix_cfg0;
    DsIpfixConfig1_m  ipfix_cfg1;
    IpfixIngSamplingProfile_m  ipfix_sampling_cfg;

    sys_ipfix_sample_profile_t* p_get_sample_prf = NULL;
    sys_ipfix_sample_profile_t new_sample_prf;
    sys_ipfix_sample_profile_t old_sample_prf;
    sys_ipfix_sample_profile_t tmp_sample_prf;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if((CTC_EGRESS == p_flow_cfg->dir) && (p_flow_cfg->sample_mode || p_flow_cfg->sample_type || p_flow_cfg->sample_interval))
    {
        return CTC_E_NOT_SUPPORT;
    }
    for(loop_i=0; loop_i<32; loop_i++)
    {
        if(CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, loop_i))
        {
            CTC_ERROR_RETURN(_sys_tmm_ipfix_get_export_reason_dir(loop_i, &dir));
            if(((CTC_INGRESS == p_flow_cfg->dir) && (CTC_EGRESS == dir)) ||((CTC_EGRESS == p_flow_cfg->dir) && (CTC_INGRESS == dir)))
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "export reason dir error, flow dir:%d, export reason dir:%d\n", p_flow_cfg->dir, dir);
                return CTC_E_INVALID_PARAM;
            }
        }
    }

    if(p_flow_cfg->drop_report_bmp[0] ||p_flow_cfg->drop_report_bmp[1])
    {
        for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)
        {
            if(CTC_BMP_ISSET(p_flow_cfg->drop_report_bmp, loop_i))
            {
                CTC_ERROR_RETURN(_sys_tmm_ipfix_get_drop_dir(loop_i, &dir));
                if(((CTC_INGRESS == p_flow_cfg->dir) && (CTC_EGRESS == dir)) ||((CTC_EGRESS == p_flow_cfg->dir) && (CTC_INGRESS == dir)))
                {
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "drop reason dir error, flow dir:%d, drop reason dir:%d\n", p_flow_cfg->dir, dir);
                    return CTC_E_INVALID_PARAM;
                }
            }
        }
    }

    /*Ignore drop reason, if set 1, indicates drop_pkt_mode drop reason bitmap useless*/
    if((0 == p_flow_cfg->drop_pkt_mode)&&p_usw_ipfix_master[lchip]->ignore_drop_reason)
    {
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&ipfix_cfg0, 0, sizeof(ipfix_cfg0));
    sal_memset(&ipfix_cfg1, 0, sizeof(ipfix_cfg1));
    sal_memset(&ipfix_sampling_cfg, 0, sizeof(ipfix_sampling_cfg));
    sal_memset(&new_sample_prf, 0, sizeof(new_sample_prf));
    sal_memset(&old_sample_prf, 0, sizeof(old_sample_prf));
    sal_memset(&tmp_sample_prf, 0, sizeof(tmp_sample_prf));
    if(CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_EXPIRED))
    {
         return CTC_E_INVALID_PARAM;
    }

    if(!CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_TC_MARK))
    {
        /* ipfix droppkt reason, dscp:bit0,bit1 */
        value_a = 2;
        cmd = DRV_IOW( IpePreLookupCtl_t, IpePreLookupCtl_tosShiftMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    }

    CTC_ERROR_RETURN(_sys_usw_ipfix_map_reason_ctc_to_sys_bmp(lchip, p_flow_cfg, &sys_suppress_reason_bmp, &sys_deny_export_reason_bmp));

    sample_cfg_table_id = IpfixSamplingProfile_t;
    cfg_table_id = (p_flow_cfg->dir == CTC_INGRESS) ? DsIpfixConfig0_t : DsIpfixConfig1_t;

    if(p_flow_cfg->dir == CTC_INGRESS)
    {
        cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg0));
    }
    else
    {
        cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg1));
    }
    cmd = DRV_IOR( sample_cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg));

    sample_enable = GetDsIpfixConfig0(V, samplingEn_f, &ipfix_cfg0);
    sample_profile_index = GetDsIpfixConfig0(V, samplingProfileIndex_f, &ipfix_cfg0);

    step = IpfixSamplingProfile_array_1_samplingPktInterval_f - IpfixSamplingProfile_array_0_samplingPktInterval_f;

    if (p_flow_cfg->dir == CTC_INGRESS)
    {
        if (sample_enable)
        {
            old_sample_prf.dir = p_flow_cfg->dir;
            old_sample_prf.mode = GetIpfixSamplingProfile(V, \
                    array_0_samplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg);
            old_sample_prf.interval = p_usw_ipfix_master[lchip]->sip_interval[sample_profile_index];
            old_sample_prf.mode |= GetIpfixSamplingProfile(V, \
                    array_0_countBasedSamplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg) << 1;
        }

        if (p_flow_cfg->sample_interval != 0) /*add or update*/
        {
            uint16 drv_interval = 0;
            new_sample_prf.dir = p_flow_cfg->dir;
            new_sample_prf.interval = p_flow_cfg->sample_interval;
            new_sample_prf.mode = (!!p_flow_cfg->sample_type << 1) | (!!p_flow_cfg->sample_mode);

            ret = ctc_spool_add(p_usw_ipfix_master[lchip]->sample_spool, &new_sample_prf, &old_sample_prf, &p_get_sample_prf);
            if (ret)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "add sample spool error, %%ret=%d\n", ret);
                return ret;
            }

            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER, 1);
            p_usw_ipfix_master[lchip]->sip_interval[p_get_sample_prf->ad_index] = p_flow_cfg->sample_interval;

            /*write hw*/
            sample_profile_index = p_get_sample_prf->ad_index;
            _sys_usw_ipfix_sample_interval_convert(lchip, p_get_sample_prf, &drv_interval);
            SetIpfixSamplingProfile(V, array_0_samplingPktInterval_f + step*sample_profile_index, &ipfix_sampling_cfg, drv_interval);
            SetIpfixSamplingProfile(V, array_0_samplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg, p_get_sample_prf->mode&0x01);
            SetIpfixSamplingProfile(V, array_0_countBasedSamplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg, (p_get_sample_prf->mode >> 1)&0x01);

            SetDsIpfixConfig0(V, samplingProfileIndex_f, &ipfix_cfg0, p_get_sample_prf->ad_index);
            SetDsIpfixConfig0(V, samplingEn_f, &ipfix_cfg0, 1);
            sal_memcpy(&tmp_sample_prf, &new_sample_prf, sizeof(sys_ipfix_sample_profile_t)); /* for error rollback*/
        }
        else if(sample_enable)
        {
            ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->sample_spool, &old_sample_prf, &p_get_sample_prf);
            if (ret)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove sample spool error, %%ret=%d\n", ret);
                return ret;
            }
            /*write hw*/
            SetDsIpfixConfig0(V, samplingProfileIndex_f, &ipfix_cfg0, 0);
            SetDsIpfixConfig0(V, samplingEn_f, &ipfix_cfg0, 0);
        }

        if(CTC_IPFIX_FLOW_TYPE_ALL_PACKET == p_flow_cfg->flow_type)
        {
            flow_type = 0;
        }
        else if(CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET == p_flow_cfg->flow_type)
        {
            flow_type = 1;
        }
        else if(CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET == p_flow_cfg->flow_type)
        {
            flow_type = 2;
        }
        SetDsIpfixConfig0(V, flowType_f, &ipfix_cfg0, flow_type);

        SetDsIpfixConfig0(V, sessionNumLimitEn_f, &ipfix_cfg0, !!p_flow_cfg->learn_disable);
        SetDsIpfixConfig0(V, tcpSessionEndDetectDisable_f, &ipfix_cfg0, !!p_flow_cfg->tcp_end_detect_disable);
        SetDsIpfixConfig0(V, ipfixMirrorCount_f, &ipfix_cfg0, p_flow_cfg->log_pkt_count);
        SetDsIpfixConfig0(V, disableCaptureEvent_f, &ipfix_cfg0, sys_suppress_reason_bmp);
        SetDsIpfixConfig0(V, denySendDmaBitMap_f, &ipfix_cfg0, sys_deny_export_reason_bmp);
        /* igs ipfix drop classid spool */
        CTC_ERROR_GOTO( _sys_tmm_ipfix_set_flow_drop_classid(lchip, &ipfix_cfg0, NULL, p_flow_cfg), ret, error_pro);
        SetDsIpfixConfig0(V, recordDiscardVectorEn_f, &ipfix_cfg0, !p_flow_cfg->drop_pkt_mode);
        cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg0));
        cmd = DRV_IOW( sample_cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg));
    }
    else
    {
        SetDsIpfixConfig1(V, disableCaptureEvent_f, &ipfix_cfg1,sys_suppress_reason_bmp);
        /* egs ipfix drop classid spool */
        CTC_ERROR_RETURN(_sys_tmm_ipfix_set_flow_drop_classid(lchip, NULL, &ipfix_cfg1, p_flow_cfg));
        SetDsIpfixConfig1(V, recordDiscardVectorEn_f, &ipfix_cfg1, !p_flow_cfg->drop_pkt_mode);
        cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg1));

        cmd = DRV_IOW(DsIpfixConfig0_t, DsIpfixConfig0_denySendDmaBitMap_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &sys_deny_export_reason_bmp));
    }
    return CTC_E_NONE;

error_pro:
    if(p_flow_cfg->sample_interval != 0)
    {
        ctc_spool_remove(p_usw_ipfix_master[lchip]->sample_spool, &tmp_sample_prf, &p_get_sample_prf);
    }
    else if(sample_enable)
    {
        ctc_spool_add(p_usw_ipfix_master[lchip]->sample_spool, &old_sample_prf, NULL, NULL);
    }
    return ret;
}

int32
sys_tmm_ipfix_get_flow_cfg(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32 cmd = 0;
    uint32  samping_idx = 0;
    uint8 flow_type = 0;
    uint8 step = 0;
    uint32 sys_deny_reason_bmp = 0;
    uint32 sys_suppress_reason_bmp = 0;
    uint32  cfg_table_id;
    uint32  sample_cfg_table_id;
    IpfixSamplingProfile_m  ipfix_sampleing_cfg;
    DsIpfixConfig0_m  ipfix_cfg0;
    DsIpfixConfig1_m  ipfix_cfg1;
    uint32 hw_drop_report_bmp[2] = {0};

    sal_memset(&ipfix_cfg0, 0, sizeof(ipfix_cfg0));
    sal_memset(&ipfix_cfg1, 0, sizeof(ipfix_cfg1));

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    step = IpfixSamplingProfile_array_1_samplingPktInterval_f - IpfixSamplingProfile_array_0_samplingPktInterval_f;

    sample_cfg_table_id = IpfixSamplingProfile_t;
    cfg_table_id = (p_flow_cfg->dir == CTC_INGRESS) ? DsIpfixConfig0_t : DsIpfixConfig1_t;

    if(p_flow_cfg->dir == CTC_INGRESS)
    {
        cmd = DRV_IOR( sample_cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampleing_cfg));
        cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg0));

        p_flow_cfg->tcp_end_detect_disable = GetDsIpfixConfig0(V, tcpSessionEndDetectDisable_f, &ipfix_cfg0);
        p_flow_cfg->learn_disable = GetDsIpfixConfig0(V, sessionNumLimitEn_f, &ipfix_cfg0);
        p_flow_cfg->log_pkt_count = GetDsIpfixConfig0(V, ipfixMirrorCount_f, &ipfix_cfg0);
        flow_type = GetDsIpfixConfig0(V, flowType_f, &ipfix_cfg0);
        if(0 == flow_type)
        {
            p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_ALL_PACKET;
        }
        else if(1 == flow_type)
        {
            p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET;
        }
        else if(2 == flow_type)
        {
            p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET;
        }

        if(GetDsIpfixConfig0(V, samplingEn_f, &ipfix_cfg0))
        {
            samping_idx = GetDsIpfixConfig0(V, samplingProfileIndex_f, &ipfix_cfg0);
            p_flow_cfg->sample_mode = GetIpfixSamplingProfile(V, array_0_samplingMode_f + samping_idx*step, &ipfix_sampleing_cfg);
            p_flow_cfg->sample_type = GetIpfixSamplingProfile(V, array_0_countBasedSamplingMode_f+samping_idx*step, &ipfix_sampleing_cfg);

            if(p_flow_cfg->dir == CTC_INGRESS)
            {
                p_flow_cfg->sample_interval = p_usw_ipfix_master[lchip]->sip_interval[samping_idx];
            }
            else
            {
                p_flow_cfg->sample_interval = p_usw_ipfix_master[lchip]->sip_interval[samping_idx+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)];
            }
        }
        p_flow_cfg->drop_pkt_mode = !GetDsIpfixConfig0(V, recordDiscardVectorEn_f, &ipfix_cfg0);
        sys_suppress_reason_bmp = GetDsIpfixConfig0(V, disableCaptureEvent_f, &ipfix_cfg0);
        sys_deny_reason_bmp = GetDsIpfixConfig0(V, denySendDmaBitMap_f, &ipfix_cfg0);
        _sys_usw_ipfix_map_reason_sys_to_ctc_bmp(lchip, sys_suppress_reason_bmp, sys_deny_reason_bmp, p_flow_cfg);
        GetDsIpfixConfig0(A, discardVectorExportBmp_f, &ipfix_cfg0, hw_drop_report_bmp);
    }
    else
    {
        cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg1));
        p_flow_cfg->drop_pkt_mode = !GetDsIpfixConfig1(V, recordDiscardVectorEn_f, &ipfix_cfg1);
        sys_suppress_reason_bmp = GetDsIpfixConfig1(V, disableCaptureEvent_f, &ipfix_cfg1);
        cmd = DRV_IOR( DsIpfixConfig0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg0));
        sys_deny_reason_bmp = GetDsIpfixConfig0(V, denySendDmaBitMap_f, &ipfix_cfg0);
        _sys_usw_ipfix_map_reason_sys_to_ctc_bmp(lchip, sys_suppress_reason_bmp,sys_deny_reason_bmp, p_flow_cfg);
        GetDsIpfixConfig1(A, discardVectorExportBmp_f, &ipfix_cfg1, hw_drop_report_bmp);
    }
    CTC_BMP_UNSET(hw_drop_report_bmp, CTC_DROP_MAX);
    sal_memcpy(p_flow_cfg->drop_report_bmp, hw_drop_report_bmp, sizeof(hw_drop_report_bmp));
    return CTC_E_NONE;
}
STATIC int32
_sys_tmm_ipfix_decode_l2_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_mac_field_sel_t *field_sel = &field_sel_tmp.u.mac;

    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    sys_ipfix_l2_hashkey_decode_t *pkey_d = (sys_ipfix_l2_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->ether_type = pkey_d->etherType;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_MAC, &field_sel_tmp));

    p_data->cvlan = pkey_d->cvlanId;
    p_data->cvlan_cfi = pkey_d->cvtagCfi;
    p_data->cvlan_prio = pkey_d->cvtagCos;
    if (pkey_d->cvlanIdValid)
    {
        p_data->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
    }
    p_data->svlan = pkey_d->svlanId;
    p_data->svlan_cfi = pkey_d->svtagCfi;
    p_data->svlan_prio = pkey_d->svtagCos;
    if (pkey_d->svlanIdValid)
    {
        p_data->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
    }
    if(field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort);
    }
    else if(field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort;
    }
    else if(field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort);
    }

    /* macda macsa dst_cid src_cid */
    mac_da[0]= pkey_d->macDa_0_31;
    mac_da[1]= pkey_d->macDa_32_47;
    mac_sa[0] = pkey_d->macSa_0_15 | ((pkey_d->macSa_16_39&0xFFFF) << 16);
    mac_sa[1] = (pkey_d->macSa_16_39 >> 16) | (pkey_d->macSa_40_47 << 8);

    p_data->dst_cid = pkey_d->destCategoryId;
    if (pkey_d->destCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
    }
    p_data->src_cid = pkey_d->srcCategoryId;
    if (pkey_d->srcCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
    }

    SYS_USW_SET_USER_MAC(p_data->dst_mac, mac_da);
    SYS_USW_SET_USER_MAC(p_data->src_mac, mac_sa);
    p_data->fid = pkey_d->vsiId; /* TMM ...*/

    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_decode_l2l3_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_l2_l3_field_sel_t *field_sel = &field_sel_tmp.u.l2_l3;

    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    sys_ipfix_l2l3_hashkey_decode_t *pkey_d = (sys_ipfix_l2l3_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);

    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_L2_L3, &field_sel_tmp));


    p_data->ether_type = pkey_d->etherType_0_7 | (pkey_d->etherType_8_15<<8);

    if (field_sel->ctag_cfi||field_sel->ctag_cos||field_sel->ctag_vlan)
    {
        p_data->cvlan = pkey_d->cvlanId;
        p_data->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
    }
    p_data->cvlan_prio = pkey_d->cvtagCos;
    p_data->cvlan_cfi = pkey_d->cvtagCfi;

    if (field_sel->stag_cfi||field_sel->stag_cos||field_sel->stag_vlan)
    {
        p_data->svlan = pkey_d->svlanId;
        p_data->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
    }
    p_data->svlan_prio = pkey_d->svtagCos;
    p_data->svlan_cfi = pkey_d->svtagCfi;

    if(field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort);
    }
    else if(field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort;
    }
    else if(field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort);
    }

    mac_sa[0]= pkey_d->macSa_0_9 | (pkey_d->macSa_10_41&0x3FFFFF)<<10;
    mac_sa[1]= (pkey_d->macSa_10_41>>22) | pkey_d->macSa_42_47<<10;
    mac_da[0] = pkey_d->macDa_0_25 | (pkey_d->macDa_26_47&0x3F)<<26;
    mac_da[1] = pkey_d->macDa_26_47>>6;
    SYS_USW_SET_USER_MAC(p_data->src_mac, mac_sa);
    SYS_USW_SET_USER_MAC(p_data->dst_mac, mac_da);

    /* parser l3 information */

    if (field_sel->dst_cid)
    {
        p_data->dst_cid = pkey_d->destCategoryId_0_6 | (pkey_d->destCategoryId_7_15<<7);
        if (pkey_d->destCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }

    if (field_sel->ip_da)
    {
        p_l3_info->ipv4.ipda = pkey_d->uL3__0_23 | (pkey_d->uL3__24_47&0xFF)<<24;
        p_l3_info->ipv4.ipda_masklen = field_sel->ip_da_mask;
    }

    if (field_sel->src_cid)
    {
        p_data->src_cid = pkey_d->srcCategoryId_0_14 | (pkey_d->srcCategoryId_15_15<<15);
        if (pkey_d->srcCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }

    if (field_sel->ip_sa)
    {
        p_l3_info->ipv4.ipsa = (pkey_d->uL3__24_47>>8) | (pkey_d->uL3__48_76&0xFFFF)<<16;
        p_l3_info->ipv4.ipsa_masklen = field_sel->ip_sa_mask;
    }

    if(field_sel->ttl)
    {
        p_l3_info->ipv4.ttl = (pkey_d->uL3__48_76>>22) | (pkey_d->uL3__77_99&0x1)<<7;
    }
    if(field_sel->dscp)
    {
        p_l3_info->ipv4.dscp = (pkey_d->uL3__48_76>>16)&0x3F;
    }
    if(field_sel->ecn)
    {
        p_l3_info->ipv4.ecn = (pkey_d->uL3__77_99>>1)&0x3;
    }

    if(field_sel->label_num)
    {
        p_l3_info->mpls.label_num = pkey_d->uL3__77_99>>19;
    }
    if(field_sel->mpls_label0_exp)
    {
        p_l3_info->mpls.label[0].exp = (pkey_d->uL3__48_76>>25)&0x7;
    }
    if(field_sel->mpls_label0_label)
    {
        p_l3_info->mpls.label[0].label = pkey_d->uL3__48_76>>28 | (pkey_d->uL3__77_99&0x7FFFF)<<1;
    }
    if(field_sel->mpls_label0_s)
    {
        p_l3_info->mpls.label[0].sbit = (pkey_d->uL3__48_76>>24)&0x1;
    }
    if(field_sel->mpls_label0_ttl)
    {
        p_l3_info->mpls.label[0].ttl = (pkey_d->uL3__48_76>>16)&0xFF;
    }
    if(field_sel->mpls_label1_exp)
    {
        p_l3_info->mpls.label[1].exp = (pkey_d->uL3__24_47>>17)&0x7;
    }
    if(field_sel->mpls_label1_label)
    {
        p_l3_info->mpls.label[1].label = pkey_d->uL3__24_47>>20 | ((pkey_d->uL3__48_76&0xFFFF)<<4);
    }
    if(field_sel->mpls_label1_s)
    {
        p_l3_info->mpls.label[1].sbit = (pkey_d->uL3__24_47>>16)&0x1;
    }
    if(field_sel->mpls_label1_ttl)
    {
        p_l3_info->mpls.label[1].ttl = (pkey_d->uL3__24_47>>8)&0xFF;
    }
    if(field_sel->mpls_label2_exp)
    {
        p_l3_info->mpls.label[2].exp = (pkey_d->uL3__0_23>>9)&0x7;
    }
    if(field_sel->mpls_label2_label)
    {
        p_l3_info->mpls.label[2].label = pkey_d->uL3__0_23>>12 | ((pkey_d->uL3__24_47&0xFF)<<12);
    }
    if(field_sel->mpls_label2_s)
    {
        p_l3_info->mpls.label[2].sbit = (pkey_d->uL3__0_23>>8)&0x1;
    }
    if(field_sel->mpls_label2_ttl)
    {
        p_l3_info->mpls.label[2].ttl = pkey_d->uL3__0_23&0xFF;
    }

    if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == pkey_d->layer3HeaderProtocol) && (field_sel->icmp_code || field_sel->icmp_type))
    {
        p_l4_info->icmp.icmpcode = pkey_d->uL4__0_31>>24;
        p_l4_info->icmp.icmp_type = pkey_d->uL4__32_39&0xFF;
    }
    else if((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == pkey_d->layer3HeaderProtocol) &&field_sel->igmp_type)
    {
        p_l4_info->igmp.igmp_type = pkey_d->uL4__32_39&0xFF;
    }
    else if((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP == pkey_d->layer3HeaderProtocol || SYS_L4_PROTOCOL_UDP == pkey_d->layer3HeaderProtocol ))
            && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_l4_info->l4_port.dest_port = (pkey_d->uL4__0_31>>8)&0xFFFFFF;
        p_l4_info->l4_port.source_port = pkey_d->uL4__0_31>>24 | (pkey_d->uL4__32_39&0xFF)<<8;
    }

    /* process l4 information */
    p_l4_info->aware_tunnel_info_en = pkey_d->isMergeKey;

    if (p_l4_info->aware_tunnel_info_en)
    {
        switch (pkey_d->mergeDataType)
        {
            case 1:
                p_l4_info->vni = pkey_d->mergeData_0_8 | (pkey_d->mergeData_9_31<<9);
                break;
            case 2:
                p_l4_info->gre_key = pkey_d->mergeData_0_8 | (pkey_d->mergeData_9_31<<9);
                break;
            default:
                break;
        }
    }
    else
    {
        if (field_sel->gre_key || field_sel->nvgre_key)
        {
            p_l4_info->gre_key = pkey_d->uL4__0_31;
        }
        else if (field_sel->vxlan_vni)
        {
            p_l4_info->vni = pkey_d->uL4__0_31&0xFFFFFF;
        }
    }

    /*From TM.MX, the merge data is not union with the following fields*/
    p_l4_info->type.ip_protocol = pkey_d->layer3HeaderProtocol;

    if (field_sel->tcp_flags)
    {
        p_l4_info->tcp_flags = pkey_d->uL4__0_31&0xFF;
    }
    if (field_sel->ip_frag)
    {
        p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG((pkey_d->uL3__77_99 >> 3)&0x3);
    }
    if (field_sel->ip_identification)
    {
        p_l3_info->ipv4.ip_identification =  (pkey_d->uL3__77_99 >> 5)&0xFFFF;
    }
    if (field_sel->vrfid)
    {
        p_l3_info->vrfid = pkey_d->vrfId_0_12 | (pkey_d->vrfId_13_13 << 13);
    }
    if (field_sel->fid)
    {
        p_data->fid = pkey_d->vsiId; /* TMM ...*/
    }

    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_decode_ipv4_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv4_field_sel_t *field_sel = &field_sel_tmp.u.ipv4;

    uint8 share_field_mode=0;
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    sys_ipfix_ipv4_hashkey_decode_t *pkey_d = (sys_ipfix_ipv4_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);

    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &field_sel_tmp));

    if(field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort);
    }
    else if(field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort;
    }
    else if(field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort);
    }

    p_l3_info->ipv4.dscp = pkey_d->dscp;
    p_l3_info->ipv4.ttl = pkey_d->ttl;
    p_l3_info->ipv4.ecn = pkey_d->ecn_0_0 | pkey_d->ecn_1_1<<1;
    p_data->dst_cid = pkey_d->destCategoryId_0_3 | (pkey_d->destCategoryId_4_15<<4);
    if (pkey_d->destCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
    }
    p_l3_info->ipv4.ipda = pkey_d->ipDa_0_15 | (pkey_d->ipDa_16_31<<16);
    p_l3_info->ipv4.ipda_masklen = field_sel->ip_da_mask;
    p_data->src_cid = pkey_d->srcCategoryId;
    if (pkey_d->srcCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
    }
    p_l3_info->ipv4.ipsa = pkey_d->ipSa_0_7 | (pkey_d->ipSa_8_31<<8);
    p_l3_info->ipv4.ipsa_masklen = field_sel->ip_sa_mask;

    p_l4_info->type.ip_protocol = pkey_d->layer3HeaderProtocol_0_4 | (pkey_d->layer3HeaderProtocol_5_7<<5);

    if (field_sel->vxlan_vni)
    {
       p_l4_info->vni = pkey_d->uL4__0_15 | ((pkey_d->uL4__16_31&0xFF)<<16);
    }
    else if(field_sel->gre_key || field_sel->nvgre_key)
    {
       p_l4_info->gre_key = pkey_d->uL4__0_15 | (pkey_d->uL4__16_31<<16);
    }
    else if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP ==  p_l4_info->type.ip_protocol) && (field_sel->icmp_code || field_sel->icmp_type))
    {
        p_l4_info->icmp.icmpcode = pkey_d->uL4__16_31&0xff;
        p_l4_info->icmp.icmp_type = (pkey_d->uL4__16_31>>8)&0xff;
    }
    else if((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP ==  p_l4_info->type.ip_protocol) && field_sel->igmp_type)
    {
        p_l4_info->igmp.igmp_type = (pkey_d->uL4__16_31>>8)&0xff;
    }
    else if ((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP == p_l4_info->type.ip_protocol || SYS_L4_PROTOCOL_UDP == p_l4_info->type.ip_protocol )) && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_l4_info->l4_port.dest_port = pkey_d->uL4__0_15;
        p_l4_info->l4_port.source_port = pkey_d->uL4__16_31;
    }

    /*share field*/

    p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(pkey_d->fragInfo);
    p_l4_info->tcp_flags = pkey_d->tcpFlags;
    if (field_sel->ip_identification)
    {
        share_field_mode = 1;
    }
    else if (field_sel->ip_pkt_len)
    {
        share_field_mode = 2;
    }
    switch (share_field_mode)
    {
        case 0:
            p_l3_info->vrfid = pkey_d->uShareField_&0x3FFF;
            break;
        case 1:
            p_l3_info->ipv4.ip_identification = pkey_d->uShareField_;
            break;
        default:/*case 2:*/
            p_l3_info->ipv4.ip_pkt_len = pkey_d->uShareField_&0x3FFF;
            break;
    }

    p_data->fid = pkey_d->vsiId; /* TMM ...*/
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_decode_ipv6_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv6_field_sel_t *field_sel = &field_sel_tmp.u.ipv6;
    uint32 merge_data[2] = {0};
    sys_ipfix_ipv6_hashkey_decode_t *pkey_d = (sys_ipfix_ipv6_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel_tmp));

    if(field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort);
    }
    else if(field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort;
    }
    else if(field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort);
    }

    p_data->l3_info.ipv6.dscp = pkey_d->dscp;
    p_data->l4_info.type.ip_protocol = pkey_d->layer3HeaderProtocol;
    p_data->l4_info.aware_tunnel_info_en = pkey_d->isMergeKey;

    if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP ==  p_data->l4_info.type.ip_protocol ) && (field_sel->icmp_type || field_sel->icmp_code))
    {
      p_data->l4_info.icmp.icmpcode = (pkey_d->uL4_>>16)&0xff;
      p_data->l4_info.icmp.icmp_type = (pkey_d->uL4_>>24)&0xff;
    }
    else if(field_sel->igmp_type)
    {
      p_data->l4_info.igmp.igmp_type = (pkey_d->uL4_>>24)&0xff;
    }
    else if((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP ==  p_data->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP == p_data->l4_info.type.ip_protocol))
            && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
      p_data->l4_info.l4_port.dest_port = pkey_d->uL4_&0xffff;
      p_data->l4_info.l4_port.source_port = pkey_d->uL4_>>16;
    }

    if(!p_data->l4_info.aware_tunnel_info_en)
    {
        if (field_sel->gre_key || field_sel->nvgre_key)
        {
            p_data->l4_info.gre_key = pkey_d->uL4_;
        }
        else if (field_sel->vxlan_vni)
        {
            p_data->l4_info.vni = pkey_d->uL4_&0xFFFFFF;
        }
    }

    p_data->l3_info.ipv6.ipsa[0] = (pkey_d->ipSa_83_114>>13) |  (pkey_d->ipSa_115_127<<19);
    p_data->l3_info.ipv6.ipsa[1] = (pkey_d->ipSa_54_82>>10) |  (pkey_d->ipSa_83_114&0x1FFF)<<19;
    p_data->l3_info.ipv6.ipsa[2] = (pkey_d->ipSa_30_53>>2) |  (pkey_d->ipSa_54_82&0x3FF)<<22;
    p_data->l3_info.ipv6.ipsa[3] = pkey_d->ipSa_0_29 |  (pkey_d->ipSa_30_53&0x3)<<30;

    p_data->l3_info.ipv6.ipda[0] = pkey_d->ipDa_94_125>>2 |(pkey_d->ipDa_126_127<<30);
    p_data->l3_info.ipv6.ipda[1] = pkey_d->ipDa_41_64>>23 | (pkey_d->ipDa_65_93<<1) | (pkey_d->ipDa_94_125&0x3)<<30;
    p_data->l3_info.ipv6.ipda[2] = pkey_d->ipDa_9_40>>23 | (pkey_d->ipDa_41_64&0x7FFFFF)<<9;
    p_data->l3_info.ipv6.ipda[3] = pkey_d->ipDa_0_8 | (pkey_d->ipDa_9_40&0x7FFFFF)<<9;

    if (field_sel->src_cid)
    {
        p_data->src_cid = pkey_d->srcCategoryId_0_14 | (pkey_d->srcCategoryId_15_15<<15);
        if (pkey_d->srcCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    if (field_sel->dst_cid)
    {
        p_data->dst_cid = pkey_d->destCategoryId;
        if (pkey_d->destCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    if (field_sel->ip_frag)
    {
        p_data->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(pkey_d->fragInfo);
    }
    if (field_sel->ecn)
    {
        p_data->l3_info.ipv6.ecn = pkey_d->ecn;
    }
    if (field_sel->ttl)
    {
        p_data->l3_info.ipv6.ttl = pkey_d->ttl;
    }
    if (field_sel->flow_label)
    {
        p_data->l3_info.ipv6.flow_label = pkey_d->ipv6FlowLabel_0_8 | pkey_d->ipv6FlowLabel_9_19<<9;
    }
    if (field_sel->tcp_flags)
    {
        p_data->l4_info.tcp_flags = pkey_d->tcpFlags;
    }
    if (p_data->l4_info.aware_tunnel_info_en)
    {
        merge_data[0]=pkey_d->mergeData_0_21 | (pkey_d->mergeData_22_31<<22);
        switch (pkey_d->mergeDataType)
        {
            case SYS_IPFIX_MERGE_TYPE_VXLAN:
                p_data->l4_info.vni = merge_data[0]&0xFFFFFF;
                break;
            case SYS_IPFIX_MERGE_TYPE_GRE:
                p_data->l4_info.gre_key = merge_data[0];
                break;
            default:
                break;
        }
    }
    p_data->l3_info.ipv6.ipda_masklen = field_sel->ip_da_mask;
    p_data->l3_info.ipv6.ipsa_masklen = field_sel->ip_sa_mask;
    p_data->fid = pkey_d->vsiId_0_4 | (pkey_d->vsiId_5_14<<5); /* TMM ...*/
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_decode_mpls_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_mpls_field_sel_t *field_sel = &field_sel_tmp.u.mpls;

    ctc_ipfix_l3_info_t* p_l3_info;
    sys_ipfix_mpls_hashkey_decode_t *pkey_d = (sys_ipfix_mpls_hashkey_decode_t*)p_key;
    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_MPLS, &field_sel_tmp));

    if(field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort);
    }
    else if(field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort;
    }
    else if(field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort);
    }

    p_l3_info->mpls.label_num = pkey_d->labelNum;
    p_l3_info->mpls.label[0].exp = pkey_d->mplsExp0;
    p_l3_info->mpls.label[0].label = pkey_d->mplsLabel0;
    p_l3_info->mpls.label[0].sbit = pkey_d->mplsSbit0;
    p_l3_info->mpls.label[0].ttl = pkey_d->mplsTtl0;
    p_l3_info->mpls.label[1].exp = pkey_d->mplsExp1;
    p_l3_info->mpls.label[1].label = pkey_d->mplsLabel1;
    p_l3_info->mpls.label[1].sbit = pkey_d->mplsSbit1;
    p_l3_info->mpls.label[1].ttl = pkey_d->mplsTtl1;
    p_l3_info->mpls.label[2].exp = pkey_d->mplsExp2;
    p_l3_info->mpls.label[2].label = pkey_d->mplsLabel2;
    p_l3_info->mpls.label[2].sbit = pkey_d->mplsSbit2;
    p_l3_info->mpls.label[2].ttl = pkey_d->mplsTtl2;
    p_data->fid = pkey_d->vsiId; /* TMM ...*/
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_decode_v4_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv4_field_sel_t *field_sel = &field_sel_tmp.u.ipv4;
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    sys_ipfix_ipv4_short_hashkey_decode_t *pkey_d = (sys_ipfix_ipv4_short_hashkey_decode_t*)p_key;

    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &field_sel_tmp));
    if(pkey_d->isIp)
    {
        p_l3_info->ipv4.ipda = pkey_d->uL3__16_47>>24 | (pkey_d->uL3__48_79&0xFFFFFF)<<8;
        p_l3_info->ipv4.ipda_masklen = field_sel->ip_da_mask;
        p_l3_info->ipv4.ipsa = pkey_d->uL3__48_79>>24 | pkey_d->uL3__80_103<<8;
        p_l3_info->ipv4.ipsa_masklen = field_sel->ip_sa_mask;

        p_l4_info->type.ip_protocol = (pkey_d->uL3__16_47>>16)&0xFF;


        if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP ==  p_data->l4_info.type.ip_protocol) && (field_sel->icmp_code || field_sel->icmp_type))
        {
           p_l4_info->icmp.icmpcode = pkey_d->uL3__16_47&0xFF;
           p_l4_info->icmp.icmp_type = (pkey_d->uL3__16_47>>8)&0xff;
        }
        else if((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP ==  p_data->l4_info.type.ip_protocol) && field_sel->igmp_type)
        {
           p_l4_info->igmp.igmp_type = (pkey_d->uL3__16_47>>8)&0xff;
        }
        else if ((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP ==  p_data->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP == p_data->l4_info.type.ip_protocol))
                && (field_sel->l4_src_port || field_sel->l4_dst_port))
        {
           p_l4_info->l4_port.dest_port = pkey_d->uL3__0_15;
           p_l4_info->l4_port.source_port = pkey_d->uL3__16_47&0xffff;
        }
    }
    else
    {
        p_l3_info->mpls.label_num = (pkey_d->uL3__80_103>>16)&0xF;
        p_l3_info->mpls.label[0].exp = (pkey_d->uL3__16_47>>4)&0x7;
        p_l3_info->mpls.label[0].label = pkey_d->uL3__0_15 | (pkey_d->uL3__16_47&0xF)<<16;
        p_l3_info->mpls.label[0].sbit = (pkey_d->uL3__16_47>>7)&0x1;
        p_l3_info->mpls.label[0].ttl = (pkey_d->uL3__16_47>>8)&0xFF;
        p_l3_info->mpls.label[1].exp = (pkey_d->uL3__48_79>>4)&0x7;
        p_l3_info->mpls.label[1].label = pkey_d->uL3__16_47>>16 | (pkey_d->uL3__48_79&0xF)<<16;
        p_l3_info->mpls.label[1].sbit = (pkey_d->uL3__48_79>>7)&0x1;
        p_l3_info->mpls.label[1].ttl = (pkey_d->uL3__48_79>>8)&0xFF;
        p_l3_info->mpls.label[2].exp = (pkey_d->uL3__80_103>>4)&0x7;
        p_l3_info->mpls.label[2].label = pkey_d->uL3__48_79>>16 | (pkey_d->uL3__80_103&0xF)<<16;
        p_l3_info->mpls.label[2].sbit = (pkey_d->uL3__80_103>>7)&0x1;
        p_l3_info->mpls.label[2].ttl = (pkey_d->uL3__80_103>>8)&0xFF;
        p_data->key_type = CTC_IPFIX_KEY_HASH_MPLS;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_decode_v6_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv6_field_sel_t *field_sel = &field_sel_tmp.u.ipv6;
    sys_ipfix_ipv6_short_hashkey_decode_t *pkey_d = (sys_ipfix_ipv6_short_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel_tmp));

    p_data->l4_info.type.ip_protocol = pkey_d->layer3HeaderProtocol;
    if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP ==  p_data->l4_info.type.ip_protocol) && (field_sel->icmp_type || field_sel->icmp_code))
    {
        p_data->l4_info.icmp.icmpcode = pkey_d->l4SourcePort_0_0 | (pkey_d->l4SourcePort_1_15&0x7F)<<1;
        p_data->l4_info.icmp.icmp_type = pkey_d->l4SourcePort_1_15>>7;
    }
    else if(field_sel->igmp_type)
    {
        p_data->l4_info.igmp.igmp_type =pkey_d->l4SourcePort_1_15>>7;
    }
    else if((!field_sel->ip_protocol ||(SYS_L4_PROTOCOL_TCP ==  p_data->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP == p_data->l4_info.type.ip_protocol))
            && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_data->l4_info.l4_port.dest_port = pkey_d->l4DestPort;
        p_data->l4_info.l4_port.source_port = pkey_d->l4SourcePort_0_0 | (pkey_d->l4SourcePort_1_15<<1);
    }

    p_data->l3_info.ipv6.ipsa[0] = (pkey_d->ipSaPrefix_30_61>>2) | (pkey_d->ipSaPrefix_62_63<<30);
    p_data->l3_info.ipv6.ipsa[1] = pkey_d->ipSaPrefix_0_0 | (pkey_d->ipSaPrefix_1_29<<1) | (pkey_d->ipSaPrefix_30_61&0x3)<<30;

    p_data->l3_info.ipv6.ipda[0] = pkey_d->ipDaPrefix_9_40>>23 | pkey_d->ipDaPrefix_41_63<<9;
    p_data->l3_info.ipv6.ipda[1] = pkey_d->ipDaPrefix_0_8 | (pkey_d->ipDaPrefix_9_40&0x7FFFFF)<<9;

    p_data->l3_info.ipv6.ipda_masklen = field_sel->ip_da_mask;
    p_data->l3_info.ipv6.ipsa_masklen = field_sel->ip_sa_mask;

    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_encode_v4_short_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3Ipv4ShortHashKey_m ipv4_short_key;
    IpfixShortIpv4HashFieldSelect_m hash_field;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    ctc_ipfix_hash_field_sel_t field_sel;
    uint8 is_ip = 0;

    sal_memset(&ipv4_short_key, 0, sizeof(ipv4_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &field_sel));

    SetDsIpfixL3Ipv4ShortHashKey(V, hashKeyType_f, &ipv4_short_key, SYS_IPFIX_HASH_TYPE_IPV4_SHORT);
    SetDsIpfixL3Ipv4ShortHashKey(V, flowFieldSel_f, &ipv4_short_key, p_key->field_sel_id);
    SetDsIpfixL3Ipv4ShortHashKey(V, ipfixCfgProfileId_f, &ipv4_short_key, p_key->profile_id);

    cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, cmd, &hash_field));

    is_ip = GetIpfixShortIpv4HashFieldSelect(V, isIpEn_f, &hash_field);
    SetDsIpfixL3Ipv4ShortHashKey(V, isIp_f, &ipv4_short_key, is_ip);
    if (is_ip)
    {
        /*gen l3 key*/
        if (p_key->l3_info.ipv4.ipda != 0)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_ipDa_f, &ipv4_short_key, p_key->l3_info.ipv4.ipda);
        }
        if (p_key->l3_info.ipv4.ipsa != 0 )
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_ipSa_f, &ipv4_short_key, p_key->l3_info.ipv4.ipsa);
        }

        /*gen l4 key*/
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_layer3HeaderProtocol_f, &ipv4_short_key, p_key->l4_info.type.ip_protocol);

        if ((!field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == p_key->l4_info.type.ip_protocol) && (field_sel.u.ipv4.icmp_code || field_sel.u.ipv4.icmp_type))
        {
            l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
            l4_srcport |=  (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4SourcePort_f, &ipv4_short_key, l4_srcport);
        }
        else if((!field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP ==   p_key->l4_info.type.ip_protocol) && field_sel.u.ipv4.igmp_type)
        {
            l4_srcport = p_key->l4_info.igmp.igmp_type << 8;
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4SourcePort_f, &ipv4_short_key, l4_srcport);
        }
        else if((!field_sel.u.ipv4.ip_protocol  || (SYS_L4_PROTOCOL_TCP == p_key->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP == p_key->l4_info.type.ip_protocol))
                && (field_sel.u.ipv4.l4_src_port || field_sel.u.ipv4.l4_dst_port))
        {
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4DestPort_f, &ipv4_short_key, p_key->l4_info.l4_port.dest_port);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4SourcePort_f, &ipv4_short_key, p_key->l4_info.l4_port.source_port);
        }
    }
    else
    {
        /*gen mpls key*/
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_labelNum_f, &ipv4_short_key, p_key->l3_info.mpls.label_num);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsExp0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].exp);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsLabel0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].label);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsSbit0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].sbit);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsTtl0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].ttl);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsExp1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].exp);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsLabel1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].label);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsSbit1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].sbit);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsTtl1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].ttl);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsExp2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].exp);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsLabel2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].label);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsSbit2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].sbit);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsTtl2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].ttl);
    }
    sal_memcpy((uint8*)p_data, (uint8*)&ipv4_short_key, sizeof(ipv4_short_key));
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_encode_v6_short_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3Ipv6ShortHashKey_m ipv6_short_key;
    IpfixShortIpv6HashFieldSelect_m  hash_field;
    ipv6_addr_t hw_ip6;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    ctc_ipfix_hash_field_sel_t field_sel;

    sal_memset(&ipv6_short_key, 0, sizeof(ipv6_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel));

    SetDsIpfixL3Ipv6ShortHashKey(V, hashKeyType0_f, &ipv6_short_key, SYS_IPFIX_HASH_TYPE_IPV6_SHORT);
    SetDsIpfixL3Ipv6ShortHashKey(V, hashKeyType1_f, &ipv6_short_key, SYS_IPFIX_HASH_TYPE_IPV6_SHORT);
    SetDsIpfixL3Ipv6ShortHashKey(V, flowFieldSel_f, &ipv6_short_key, p_key->field_sel_id);
    SetDsIpfixL3Ipv6ShortHashKey(V, ipfixCfgProfileId_f, &ipv6_short_key, p_key->profile_id);

    cmd = DRV_IOR(IpfixShortIpv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, cmd, &hash_field));

    SetDsIpfixL3Ipv6ShortHashKey(V, layer3HeaderProtocol_f, &ipv6_short_key, p_key->l4_info.type.ip_protocol);

    if ((!p_key->l4_info.type.ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP == p_key->l4_info.type.ip_protocol) && (field_sel.u.ipv6.icmp_code || field_sel.u.ipv6.icmp_type))
    {
        l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
        l4_srcport |= (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
        SetDsIpfixL3Ipv6ShortHashKey(V, l4SourcePort_f, &ipv6_short_key, l4_srcport);
    }
    else if(field_sel.u.ipv6.igmp_type)
    {
        SetDsIpfixL3Ipv6ShortHashKey(V, l4SourcePort_f, &ipv6_short_key, (p_key->l4_info.igmp.igmp_type << 8));
    }
    else if((!p_key->l4_info.type.ip_protocol ||(SYS_L4_PROTOCOL_TCP == p_key->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP ==p_key->l4_info.type.ip_protocol))
                && (field_sel.u.ipv6.l4_src_port || field_sel.u.ipv6.l4_dst_port))
    {
        SetDsIpfixL3Ipv6ShortHashKey(V, l4DestPort_f, &ipv6_short_key, p_key->l4_info.l4_port.dest_port);
        SetDsIpfixL3Ipv6ShortHashKey(V, l4SourcePort_f, &ipv6_short_key, p_key->l4_info.l4_port.source_port);
    }

    if ((p_key->l3_info.ipv6.ipsa_masklen > 64) || (p_key->l3_info.ipv6.ipda_masklen > 64))
    {
        return CTC_E_INVALID_PARAM;
    }
    IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
    IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);
    if(field_sel.u.ipv6.ip_da && field_sel.u.ipv6.ip_da_mask <= 64)
    {
        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipda);
        SetDsIpfixL3Ipv6ShortHashKey(A, ipDaPrefix_f, &ipv6_short_key, &(hw_ip6[2]));
    }
    if(field_sel.u.ipv6.ip_sa && field_sel.u.ipv6.ip_sa_mask <= 64)
    {
        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipsa);
        SetDsIpfixL3Ipv6ShortHashKey(A, ipSaPrefix_f, &ipv6_short_key, &(hw_ip6[2]));
    }
    sal_memcpy((uint8*)p_data, (uint8*)&ipv6_short_key, sizeof(ipv6_short_key));
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_encode_udf_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    uint32 cmd = 0;
    uint32  hw_udf[8] = {0};
    uint16 global_port = 0;
    uint16 udf_data_en[16] = {0};
    uint16  zero[16] = {0};
    uint8  udfindexmatch_valid = 0;
    uint16 udf_valid_en = 0;
    sys_acl_udf_info_t udf_info;
    DsIpfixUdfHashKey_m udf_key;
    IpfixUdfHashFieldSelect_m  hash_field;
    sal_memset(&udf_key, 0, sizeof(udf_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));


    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port, MCHIP_CAP(SYS_CAP_MAX_LOGIC_PORT));
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port, 0x7FFF );
        global_port = SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixUdfHashKey(V, hashKeyType0_f, &udf_key, 7);
    SetDsIpfixUdfHashKey(V, hashKeyType1_f, &udf_key, 7);
    SetDsIpfixUdfHashKey(V, hashKeyType2_f, &udf_key, 7);
    SetDsIpfixUdfHashKey(V, hashKeyType3_f, &udf_key, 7);
    SetDsIpfixUdfHashKey(V, flowFieldSel_f, &udf_key, p_key->field_sel_id);
    SetDsIpfixUdfHashKey(V, ipfixCfgProfileId_f, &udf_key, p_key->profile_id);
    SetDsIpfixUdfHashKey(V, globalPort_f, &udf_key, global_port);
    SetDsIpfixUdfHashKey(V, udfIndexMatchValid_f, &udf_key, SYS_IPFIX_UDF_A0_VALID);

    cmd = DRV_IOR(IpfixUdfHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    GetIpfixUdfHashFieldSelect(A, udfDataEn_f, &hash_field, udf_data_en);
    udfindexmatch_valid = GetIpfixUdfHashFieldSelect(V, udfIndexMatchValid_f, &hash_field);
    udf_valid_en = GetIpfixUdfHashFieldSelect(V, udfValidEn_f, &hash_field);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, p_key->udf_id, &udf_info));

    if((!sal_memcmp(zero, udf_data_en, 16*sizeof(uint16))) || udfindexmatch_valid || udf_valid_en)
    {
        SYS_USW_SET_HW_UDF(udf_info.granularity, hw_udf,p_key->udf);

        SetDsIpfixUdfHashKey(A, udfData_f, &udf_key, hw_udf);
    }
    SetDsIpfixUdfHashKey(V, udfValid_f, &udf_key, (udf_valid_en & ((1 << udf_info.scl_offset_num) -1)));
    sal_memcpy((uint8*)p_data, (uint8*)&udf_key, sizeof(udf_key));
    return CTC_E_NONE;
}


STATIC int32
_sys_tmm_ipfix_encode_udf_short_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    uint32 cmd = 0;
    uint16 udf_data_en[16] = {0};
    uint16  zero[16] = {0};
    uint8  udfindexmatch_valid = 0;
    uint16 udf_valid_en = 0;
    uint32     hw_udf[6] = {0};
    sys_acl_udf_info_t udf_info;
    DsIpfixUdfShortHashKey_m udf_short_key;
    IpfixUdfHashFieldSelect_m  hash_field;
    sal_memset(&udf_short_key, 0, sizeof(udf_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));

    SetDsIpfixUdfShortHashKey(V, hashKeyType0_f, &udf_short_key, 3);
    SetDsIpfixUdfShortHashKey(V, hashKeyType1_f, &udf_short_key, 3);
    SetDsIpfixUdfShortHashKey(V, flowFieldSel_f, &udf_short_key, p_key->field_sel_id);
    SetDsIpfixUdfShortHashKey(V, ipfixCfgProfileId_f, &udf_short_key, p_key->profile_id);
    SetDsIpfixUdfShortHashKey(V, udfIndexMatchValid_f, &udf_short_key, SYS_IPFIX_UDF_A0_VALID);

    cmd = DRV_IOR(IpfixUdfHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    GetIpfixUdfHashFieldSelect(A, udfDataEn_f, &hash_field, udf_data_en);
    udfindexmatch_valid = GetIpfixUdfHashFieldSelect(V, udfIndexMatchValid_f, &hash_field);
    udf_valid_en = GetIpfixUdfHashFieldSelect(V, udfValidEn_f, &hash_field);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, p_key->udf_id, &udf_info));

    if((!sal_memcmp(zero, udf_data_en, 16*sizeof(uint16))) || udfindexmatch_valid || udf_valid_en)
    {
        SYS_USW_SET_HW_UDF(udf_info.granularity, hw_udf,p_key->udf);
        if(p_usw_ipfix_master[lchip]->short_mode && hw_udf[3])
        {
            return CTC_E_INVALID_PARAM;
        }
        SetDsIpfixUdfShortHashKey(A, udfData_f, &udf_short_key, hw_udf);
    }
    SetDsIpfixUdfShortHashKey(V, udfValid_f, &udf_short_key, (udf_valid_en & ((1 << udf_info.scl_offset_num) -1)));
    sal_memcpy((uint8*)p_data, (uint8*)&udf_short_key, sizeof(udf_short_key));
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_decode_udf_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 cmd = 0;
    uint32 hw_udf[8] = {0};
    sys_acl_udf_info_t udf_info;
    uint16 udf_hit_index;
    IpfixUdfHashFieldSelect_m  hash_field;
    IpeUdfIpfixCtl_m               udf_ipfix_ctl;

    sal_memset(&hash_field, 0, sizeof(IpfixUdfHashFieldSelect_m));

    p_data->field_sel_id = GetDsIpfixUdfHashKey(V, flowFieldSel_f , p_key);
    p_data->profile_id = GetDsIpfixUdfHashKey(V, ipfixCfgProfileId_f, p_key);
    cmd = DRV_IOR(IpeUdfIpfixCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &udf_ipfix_ctl));

    udf_hit_index = GetIpeUdfIpfixCtl(V, udfIpfixMatchIndexA0_f, &udf_ipfix_ctl);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_id(lchip, udf_hit_index, &p_data->udf_id));
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, p_data->udf_id, &udf_info));
    GetDsIpfixUdfHashKey(A, udfData_f, p_key, hw_udf);

    SYS_USW_SET_USR_UDF(udf_info.granularity,  p_data->udf, hw_udf);

    cmd = DRV_IOR(IpfixUdfHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    switch(GetIpfixUdfHashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDsIpfixUdfHashKey(V, globalPort_f, p_key));
            break;
        case 2:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            p_data->logic_port = GetDsIpfixUdfHashKey(V, globalPort_f, p_key);
            break;
        case 4:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(GetDsIpfixUdfHashKey(V, globalPort_f, p_key));
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_ipfix_decode_udf_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 hw_udf[6] = {0};
    uint32 cmd = 0;
    IpeUdfIpfixCtl_m   udf_ipfix_ctl;
    sys_acl_udf_info_t udf_info;
    uint16 udf_hit_index ;

    p_data->field_sel_id = GetDsIpfixUdfShortHashKey(V, flowFieldSel_f , p_key);
    p_data->profile_id = GetDsIpfixUdfShortHashKey(V, ipfixCfgProfileId_f, p_key);


    cmd = DRV_IOR(IpeUdfIpfixCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &udf_ipfix_ctl));
    udf_hit_index = GetIpeUdfIpfixCtl(V, udfIpfixMatchIndexA0_f, &udf_ipfix_ctl);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_id(lchip, udf_hit_index, &p_data->udf_id));
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, p_data->udf_id, &udf_info));
    GetDsIpfixUdfShortHashKey(A, udfData_f, p_key, hw_udf);
    SYS_USW_SET_USR_UDF(udf_info.granularity,  p_data->udf, hw_udf);
    return CTC_E_NONE;
}

int32
_sys_tmm_ipfix_set_udf_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixUdfHashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint8 global_port_type = 0;
    uint32     hw_udf[8] = {0};
    uint32 udf_id = 0;
    sys_acl_udf_info_t udf_info;
    IpeUdfIpfixCtl_m   udf_ipfix_ctl;
    uint16 udf_hit_index ;
    sal_memset(&hash_field, 0, sizeof(IpfixUdfHashFieldSelect_m));
    
    CTC_MAX_VALUE_CHECK(field_sel->u.udf.udf_valid, 0xFF);
    SetIpfixUdfHashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.udf.profile_id);
    SetIpfixUdfHashFieldSelect(V, udfIndexMatchValid_f, &hash_field, SYS_IPFIX_UDF_A0_VALID);
    SetIpfixUdfHashFieldSelect(V, udfValidEn_f, &hash_field, field_sel->u.udf.udf_valid);

    cmd = DRV_IOR(IpeUdfIpfixCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &udf_ipfix_ctl));

    udf_hit_index = GetIpeUdfIpfixCtl(V, udfIpfixMatchIndexA0_f, &udf_ipfix_ctl);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_id(lchip, udf_hit_index, &udf_id));
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, udf_id, &udf_info));
    SYS_USW_SET_HW_UDF(udf_info.granularity, hw_udf, field_sel->u.udf.udf_data);
    if(p_usw_ipfix_master[lchip]->short_mode)
    {
        CTC_MAX_VALUE_CHECK(field_sel->u.udf.udf_valid, 0x3F);
        if( hw_udf[3] )
        {
          return CTC_E_INVALID_PARAM;
        }
    }
    SetIpfixUdfHashFieldSelect(A, udfDataEn_f, &hash_field, hw_udf);

    if(field_sel->u.udf.gport)
    {
        global_port_type = 1;
    }
    else if(field_sel->u.udf.logic_port)
    {
        global_port_type = 2;
    }
    else if(field_sel->u.udf.metadata)
    {
        global_port_type = 4;
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixUdfHashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);

    cmd = DRV_IOW(IpfixUdfHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

 int32
_sys_tmm_ipfix_set_v4_short_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixShortIpv4HashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint32 ip_prefix_len = 0;
    uint32 value = 0;

    uint8 is_icmp = field_sel->u.ipv4.icmp_code || field_sel->u.ipv4.icmp_type;
    uint8 is_igmp = !!field_sel->u.ipv4.igmp_type;
    uint8 is_l4_port = field_sel->u.ipv4.l4_src_port || field_sel->u.ipv4.l4_dst_port;
    uint8 is_protocol = !!field_sel->u.ipv4.ip_protocol;
    uint8 is_mpls = ((CTC_IPFIX_KEY_HASH_MPLS_SINGLE == field_sel->key_type)||(CTC_IPFIX_KEY_HASH_MPLS == field_sel->key_type)) && \
                (field_sel->u.mpls.label_num || \
                field_sel->u.mpls.mpls_label0_exp || \
                field_sel->u.mpls.mpls_label1_exp || \
                field_sel->u.mpls.mpls_label2_exp || \
                field_sel->u.mpls.mpls_label0_label || \
                field_sel->u.mpls.mpls_label1_label || \
                field_sel->u.mpls.mpls_label2_label || \
                field_sel->u.mpls.mpls_label0_s || \
                field_sel->u.mpls.mpls_label1_s || \
                field_sel->u.mpls.mpls_label2_s || \
                field_sel->u.mpls.mpls_label0_ttl || \
                field_sel->u.mpls.mpls_label1_ttl || \
                field_sel->u.mpls.mpls_label2_ttl);
    uint8 is_ipv4 = ((CTC_IPFIX_KEY_HASH_IPV4_SINGLE == field_sel->key_type)||(CTC_IPFIX_KEY_HASH_IPV4 == field_sel->key_type)) && \
                (field_sel->u.ipv4.ip_da || \
                field_sel->u.ipv4.ip_da_mask || \
                field_sel->u.ipv4.ip_sa || \
                field_sel->u.ipv4.ip_sa_mask || \
                field_sel->u.ipv4.ip_protocol|| \
                is_icmp || is_igmp || is_l4_port || \
                field_sel->u.ipv4.sym_session_en || \
                field_sel->u.ipv4.fid || \
                field_sel->u.ipv4.gport || \
                field_sel->u.ipv4.profile_id || \
                field_sel->u.ipv4.vrfid);

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(((CTC_IPFIX_KEY_HASH_IPV4 == field_sel->key_type)||(CTC_IPFIX_KEY_HASH_IPV4_SINGLE == field_sel->key_type)) && (is_icmp + is_igmp + is_l4_port) > 1 && !is_protocol )
    {
        return CTC_E_PARAM_CONFLICT;
    }

    sal_memset(&hash_field, 0, sizeof(IpfixShortIpv4HashFieldSelect_m));

    SetIpfixShortIpv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, is_ipv4 ? field_sel->u.ipv4.profile_id : field_sel->u.mpls.profile_id);

    if(is_ipv4)
    {
        SetIpfixShortIpv4HashFieldSelect(V, isIpEn_f, &hash_field, is_ipv4);
         if (field_sel->u.ipv4.ip_da)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.ipv4.ip_da_mask);
            ip_prefix_len = field_sel->u.ipv4.ip_da_mask - 1;

            SetIpfixShortIpv4HashFieldSelect(V,  ipDaPrefixLength_f, &hash_field, ip_prefix_len);
            SetIpfixShortIpv4HashFieldSelect(V,  ipDaEn_f, &hash_field, 1);
        }
        if (field_sel->u.ipv4.ip_sa)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.ipv4.ip_sa_mask);
            ip_prefix_len = field_sel->u.ipv4.ip_sa_mask - 1;

           SetIpfixShortIpv4HashFieldSelect(V,  ipSaPrefixLength_f, &hash_field, ip_prefix_len);
           SetIpfixShortIpv4HashFieldSelect(V,  ipSaEn_f, &hash_field, 1);
        }

        SetIpfixShortIpv4HashFieldSelect(V, layer3HeaderProtocolEn_f, &hash_field, field_sel->u.ipv4.ip_protocol);
        SetIpfixShortIpv4HashFieldSelect(V, l4DestPortEn_f, &hash_field, field_sel->u.ipv4.l4_dst_port);
        SetIpfixShortIpv4HashFieldSelect(V, l4SourcePortEn_f, &hash_field, field_sel->u.ipv4.l4_src_port);
        SetIpfixShortIpv4HashFieldSelect(V, icmpOpcodeEn_f, &hash_field, field_sel->u.ipv4.icmp_code);
        SetIpfixShortIpv4HashFieldSelect(V, icmpTypeEn_f, &hash_field, field_sel->u.ipv4.icmp_type);
        SetIpfixShortIpv4HashFieldSelect(V, igmpTypeEn_f, &hash_field, field_sel->u.ipv4.igmp_type);
        SetIpfixShortIpv4HashFieldSelect(V, ignorVxlan_f, &hash_field, 1);
        SetIpfixShortIpv4HashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.ipv4.sym_session_en);
        if (DRV_FROM_AT(lchip))
        {
            if (field_sel->u.ipv4.gport)
            {
                value = 0x1;
            }
            else if (field_sel->u.ipv4.fid)
            {
                value = 0x7;
            }
            else if (field_sel->u.ipv4.vrfid)
            {
                if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x7fff) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x4000))
                {
                    value = 0x3;
                }
                else if ( (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x4000) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x3ff))
                {
                    value = 0x4;
                }
                else if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x3ff) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x7f))
                {
                    value = 0x5;
                }
                else if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x7f) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x10))
                {
                    value = 0x6;
                }
            }
            else 
            {
                value = 0x2;
            }
            SetIpfixShortIpv4HashFieldSelect(V, flexDataType_f, &hash_field, value);
        }
    }
    else if(is_mpls)
    {
        SetIpfixShortIpv4HashFieldSelect(V, labelNumEn_f      ,&hash_field, field_sel->u.mpls.label_num);
        SetIpfixShortIpv4HashFieldSelect(V, mplsExp0En_f      ,&hash_field,field_sel->u.mpls.mpls_label0_exp);
        SetIpfixShortIpv4HashFieldSelect(V, mplsExp1En_f      ,&hash_field,field_sel->u.mpls.mpls_label1_exp);
        SetIpfixShortIpv4HashFieldSelect(V, mplsExp2En_f      ,&hash_field, field_sel->u.mpls.mpls_label2_exp);
        SetIpfixShortIpv4HashFieldSelect(V, mplsLabel0En_f    , &hash_field,field_sel->u.mpls.mpls_label0_label);
        SetIpfixShortIpv4HashFieldSelect(V, mplsLabel1En_f    , &hash_field,field_sel->u.mpls.mpls_label1_label);
        SetIpfixShortIpv4HashFieldSelect(V, mplsLabel2En_f    , &hash_field,field_sel->u.mpls.mpls_label2_label);
        SetIpfixShortIpv4HashFieldSelect(V, mplsSbit0En_f     , &hash_field,field_sel->u.mpls.mpls_label0_s);
        SetIpfixShortIpv4HashFieldSelect(V, mplsSbit1En_f     , &hash_field,field_sel->u.mpls.mpls_label1_s);
        SetIpfixShortIpv4HashFieldSelect(V, mplsSbit2En_f     , &hash_field,field_sel->u.mpls.mpls_label2_s);
        SetIpfixShortIpv4HashFieldSelect(V, mplsTtl0En_f      , &hash_field,field_sel->u.mpls.mpls_label0_ttl);
        SetIpfixShortIpv4HashFieldSelect(V, mplsTtl1En_f      , &hash_field,field_sel->u.mpls.mpls_label1_ttl);
        SetIpfixShortIpv4HashFieldSelect(V, mplsTtl2En_f      , &hash_field,field_sel->u.mpls.mpls_label2_ttl);
    }
    cmd = DRV_IOW( IpfixShortIpv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixShortIpv4HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixShortIpv4HashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

 int32
_sys_tmm_ipfix_set_v6_short_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixShortIpv6HashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint32 ip_prefix_len = 0;

    uint8 is_icmp = field_sel->u.ipv6.icmp_code || field_sel->u.ipv6.icmp_type;
    uint8 is_igmp = !!field_sel->u.ipv6.igmp_type;
    uint8 is_l4_port = field_sel->u.ipv6.l4_src_port || field_sel->u.ipv6.l4_dst_port;
    uint8 is_protocol = !!field_sel->u.ipv6.ip_protocol;

    if((is_icmp + is_igmp + is_l4_port) > 1 && !is_protocol )
    {
        return CTC_E_PARAM_CONFLICT;
    }

    sal_memset(&hash_field, 0, sizeof(IpfixShortIpv6HashFieldSelect_m));
    if (DRV_FROM_AT(lchip))
    {
        SetIpfixShortIpv6HashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);
        SetIpfixShortIpv6HashFieldSelect(V, ipSelLowEn_f, &hash_field, field_sel->u.ipv6.ipv6_low_en);
        SetIpfixShortIpv6HashFieldSelect(V, vsiIdEn_f, &hash_field, field_sel->u.ipv6.fid);
        SetIpfixShortIpv6HashFieldSelect(V, vrfIdEn_f, &hash_field, field_sel->u.ipv6.vrfid);
    }

    SetIpfixShortIpv6HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.ipv6.profile_id);

     if (field_sel->u.ipv6.ip_da)
    {
        if(((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))&&(field_sel->u.ipv6.ip_da_mask>64))
        {
            return CTC_E_INVALID_PARAM;
        }
        if((DRV_FROM_AT(lchip))&&(((field_sel->u.ipv6.ipv6_low_en)&&(field_sel->u.ipv6.ip_da_mask<64))||
            ((!(field_sel->u.ipv6.ipv6_low_en))&&(field_sel->u.ipv6.ip_da_mask>64))))
        {
            return CTC_E_INVALID_PARAM;
        }
        ip_prefix_len = (field_sel->u.ipv6.ip_da_mask/4)-1;
        SetIpfixShortIpv6HashFieldSelect(V,  ipDaPrefixLength_f, &hash_field, ip_prefix_len);
        SetIpfixShortIpv6HashFieldSelect(V,  ipDaEn_f, &hash_field, 1);
    }
    if (field_sel->u.ipv6.ip_sa)
    {
        if(((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))&&(field_sel->u.ipv6.ip_sa_mask>64))
        {
            return CTC_E_INVALID_PARAM;
        }
        if((DRV_FROM_AT(lchip))&&(((field_sel->u.ipv6.ipv6_low_en)&&(field_sel->u.ipv6.ip_sa_mask<64))||
        ((!(field_sel->u.ipv6.ipv6_low_en))&&(field_sel->u.ipv6.ip_sa_mask>64))))
        {
            return CTC_E_INVALID_PARAM;
        }
        ip_prefix_len = (field_sel->u.ipv6.ip_sa_mask/4)-1;

       SetIpfixShortIpv6HashFieldSelect(V,  ipSaPrefixLength_f, &hash_field, ip_prefix_len);
       SetIpfixShortIpv6HashFieldSelect(V,  ipSaEn_f, &hash_field, 1);
    }

    SetIpfixShortIpv6HashFieldSelect(V, layer3HeaderProtocolEn_f, &hash_field, field_sel->u.ipv6.ip_protocol);
    SetIpfixShortIpv6HashFieldSelect(V, l4DestPortEn_f, &hash_field, field_sel->u.ipv6.l4_dst_port);
    SetIpfixShortIpv6HashFieldSelect(V, l4SourcePortEn_f, &hash_field, field_sel->u.ipv6.l4_src_port);
    SetIpfixShortIpv6HashFieldSelect(V, icmpOpcodeEn_f, &hash_field, field_sel->u.ipv6.icmp_code);
    SetIpfixShortIpv6HashFieldSelect(V, icmpTypeEn_f, &hash_field, field_sel->u.ipv6.icmp_type);
    SetIpfixShortIpv6HashFieldSelect(V, igmpTypeEn_f, &hash_field, field_sel->u.ipv6.igmp_type);
    SetIpfixShortIpv6HashFieldSelect(V, ignorVxlan_f, &hash_field, 1);

    SetIpfixShortIpv6HashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.ipv6.sym_session_en);
    SetIpfixShortIpv6HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.ipv6.profile_id);

    cmd = DRV_IOW(IpfixShortIpv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW(IpfixShortIpv6HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW(IpfixShortIpv6HashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_encode_ad(uint8 lchip, sys_ipfix_param_t* param)
{
    DsIpfixSessionFullRecord0_m full_rec0;
    DsIpfixSessionFullRecord1_m full_rec1;
    DsIpfixSessionHalfRecord0_m half_rec0;
    DsIpfixSessionHalfRecord1_m half_rec1;
    uint32 dest_type = SYS_IPFIX_UNICAST_DEST;
    uint32 dest_chip_id = 0;
    uint32 lport = 0;
    uint32 byte_cnt[2] = {0};
    ctc_ipfix_data_t* p_key = param -> p_key;

    sal_memset(&full_rec0, 0, sizeof(full_rec0));
    sal_memset(&full_rec1, 0, sizeof(full_rec1));
    sal_memset(&half_rec0, 0, sizeof(half_rec0));
    sal_memset(&half_rec1, 0, sizeof(half_rec1));

    lport = SYS_MAP_CTC_GPORT_TO_DRV_LPORT(p_key->dest_gport);
    dest_chip_id = SYS_MAP_CTC_GPORT_TO_GCHIP(p_key->dest_gport);
    if (p_key->flags & CTC_IPFIX_DATA_L2_MCAST_DETECTED)
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gL2Mcast_l2McGroupId_f , &full_rec0, p_key->dest_group_id);
        dest_type = SYS_IPFIX_L2MC_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_L3_MCAST_DETECTED)
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gL3Mcast_l3McGroupId_f , &full_rec0, p_key->dest_group_id);
        dest_type = SYS_IPFIX_L3MC_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_BCAST_DETECTED)
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gBcast_floodingId_f, &full_rec0, p_key->dest_group_id);
        dest_type = SYS_IPFIX_BCAST_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_APS_DETECTED)
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gApsGroup_apsGroupId_f, &full_rec0, p_key->dest_group_id);
        dest_type = SYS_IPFIX_APS_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_ECMP_DETECTED)
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gEcmpGroup_ecmpGroupId_f, &full_rec0, p_key->dest_group_id);
        dest_type = SYS_IPFIX_ECMP_DEST;
    }

    if (p_key->flags & CTC_IPFIX_DATA_LINKAGG_DETECTED)
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gUcastToLagg_linkaggGroupId_f, &full_rec0, p_key->dest_group_id);
        dest_type = SYS_IPFIX_LAG_DEST;
    }
    else
    {
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gUcastToNormal_destChipId_f, &full_rec0, dest_chip_id);
        SetDsIpfixSessionFullRecord0(V, uDestinationInfo_gUcastToNormal_destId_f, &full_rec0, lport);
    }

    byte_cnt[0] = (uint32)p_key->byte_count;
    byte_cnt[1] = (uint32)(p_key->byte_count >> 32);
    SetDsIpfixSessionFullRecord0(V, exportReason_f, &full_rec0, p_key->export_reason);
    SetDsIpfixSessionFullRecord1(V, exportReason_f, &full_rec1, p_key->export_reason);
    SetDsIpfixSessionHalfRecord0(V, exportReason_f, &half_rec0, p_key->export_reason);
    SetDsIpfixSessionHalfRecord1(V, exportReason_f, &half_rec1, p_key->export_reason);
    SetDsIpfixSessionFullRecord0(V, expired_f, &full_rec0, (p_key->export_reason==CTC_IPFIX_REASON_EXPIRED)?1:0);
    SetDsIpfixSessionHalfRecord0(V, expired_f, &half_rec0, (p_key->export_reason==CTC_IPFIX_REASON_EXPIRED)?1:0);

    /* SetDsIpfixSessionRecord(V, droppedPacket_f , &ad_rec, (p_key->flags&CTC_IPFIX_DATA_DROP_DETECTED));  TMM discardtype how to do ? */
    SetDsIpfixSessionFullRecord0(V, destinationType_f, &full_rec0, dest_type);
    SetDsIpfixSessionFullRecord0(A, byteCount_f, &full_rec0, byte_cnt);
    SetDsIpfixSessionFullRecord1(A, byteCount_f, &full_rec1, byte_cnt);
    SetDsIpfixSessionHalfRecord0(A, byteCount_f, &half_rec0, byte_cnt);
    SetDsIpfixSessionHalfRecord1(A, byteCount_f, &half_rec1, byte_cnt);
    SetDsIpfixSessionFullRecord0(V, packetCount_f, &full_rec0, p_key->pkt_count);
    SetDsIpfixSessionFullRecord1(V, packetCount_f, &full_rec1, p_key->pkt_count);
    SetDsIpfixSessionHalfRecord0(V, packetCount_f, &half_rec0, p_key->pkt_count);
    SetDsIpfixSessionHalfRecord1(V, packetCount_f, &half_rec1, p_key->pkt_count);
    SetDsIpfixSessionFullRecord0(V, u1_gOther_fragment_f , &full_rec0, (p_key->flags&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)?1:0);
    SetDsIpfixSessionFullRecord0(V, minTtl_f, &full_rec0, p_key->min_ttl);
    SetDsIpfixSessionFullRecord0(V, maxTtl_f, &full_rec0, p_key->max_ttl);
    SetDsIpfixSessionFullRecord0(V, u1_gOther_nonFragment_f, &full_rec0, (p_key->flags&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)?0:1);
    SetDsIpfixSessionFullRecord0(V, tcpFlagsStatus_f, &full_rec0, p_key->tcp_flags);

    SetDsIpfixSessionFullRecord0(V, valid_f, &full_rec0, 1);
    SetDsIpfixSessionHalfRecord0(V, valid_f, &half_rec0, 1);

    if (p_usw_ipfix_master[lchip]->short_mode)
    {
        sal_memcpy((uint8*)(&param->igr_ad_data), (uint8*)&half_rec0, sizeof(half_rec0));
        sal_memcpy((uint8*)(&param->egs_ad_data), (uint8*)&half_rec1, sizeof(half_rec1));
    }
    else
    {
        sal_memcpy((uint8*)(&param->igr_ad_data), (uint8*)&full_rec0, sizeof(full_rec0));
        sal_memcpy((uint8*)(&param->egs_ad_data), (uint8*)&full_rec1, sizeof(full_rec1));
    }
    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_decode_ad(uint8 lchip, void* data, void* p_ad)
{
    uint32 dest_type = 0;
    uint8 dest_chip = 0;
    uint32 drop_class_vector = 0;
    ctc_ipfix_data_t* p_data = (ctc_ipfix_data_t*)data;
    sys_ipfix_half_record0_decode_t* p_ad_half0 = (sys_ipfix_half_record0_decode_t*)p_ad;
    sys_ipfix_half_record1_decode_t* p_ad_half1 = (sys_ipfix_half_record1_decode_t*)p_ad;
    sys_ipfix_full_record0_decode_t* p_ad_full0 = (sys_ipfix_full_record0_decode_t*)p_ad;
    sys_ipfix_full_record1_decode_t* p_ad_full1 = (sys_ipfix_full_record1_decode_t*)p_ad;

     /*1. Egress AD*/
    if (p_data->dir == CTC_EGRESS)
    {
        if (0 == p_ad_half1->valid)
        {
            return CTC_E_NONE;
        }
        if (DRV_CONST(DRV_IPFIX_EXPORTREASON_NO_EXPORT) == p_data->export_reason)
        {
            p_data->export_reason = ctc_export_reason[p_ad_half1->exportReason];
        }

        p_data->e_byte_count=p_ad_half1->byteCount_29_31;
        p_data->e_byte_count<<=29;
        p_data->e_byte_count|= p_ad_half1->byteCount_0_28;

        p_data->e_pkt_count = p_ad_half1->packetCount_0_22 | (p_ad_half1->packetCount_23_25<<23);
        if(0 == p_ad_half1->uDiscardInfoType)/* g1 */
        {
            p_data->e_drop_pkt_cnt[0] = (p_ad_half1->uDiscardInfo__0_28>>6)&0x3FF;
            p_data->e_drop_pkt_cnt[1] = p_ad_half1->uDiscardInfo__0_28>>22 | (p_ad_half1->uDiscardInfo__29_31<<7);
            p_data->e_drop_reason[0] = p_ad_half1->uDiscardInfo__0_28&0x3F;
            p_data->e_drop_reason[1] = (p_ad_half1->uDiscardInfo__0_28>>16)&0x3F;
        }
        else /* g2 */
        {
            drop_class_vector = p_ad_half1->uDiscardInfo__0_28 | (p_ad_half1->uDiscardInfo__29_31<<29);
            sys_tmm_ipfix_drop_clalssid_to_reason(lchip, drop_class_vector, p_data->e_drop_reason_bmp, CTC_EGRESS);
        }
        if(p_data->e_drop_reason_bmp[0] || p_data->e_drop_reason_bmp[1] || p_data->e_drop_reason[0] || p_data->e_drop_reason[1])
        {
            p_data->flags |= CTC_IPFIX_DATA_DROP_DETECTED;
        }
        if (p_usw_ipfix_master[lchip]->short_mode)
        {
            return CTC_E_NONE;
        }
        /*full*/
        p_data->max_latency = p_ad_full1->maxLatency<<5;
        p_data->min_latency = (p_ad_full1->minLatency_0_5 | (p_ad_full1->minLatency_6_23<<6))<<5;
        p_data->avg_latency = (p_ad_full1->avgLatency_0_21 | (p_ad_full1->avgLatency_22_23<<22))<<5;
        p_data->max_jitter = p_ad_full1->maxJitter<<5;
        p_data->avg_jitter = (p_ad_full1->avgJitter_0_13 | p_ad_full1->avgJitter_14_15<<14)<<5;
        p_data->last_latency = (p_ad_full1->lastPktLatency_0_13 | p_ad_full1->lastPktLatency_14_23<<14)<<5;
        return CTC_E_NONE;
    }

    /*2. Ingress AD*/
    p_data->byte_count = p_ad_half0->byteCount_0_28 | (p_ad_half0->byteCount_29_31<<29);
    p_data->pkt_count = p_ad_half0->packetCount_0_22 | (p_ad_half0->packetCount_23_25<<23);
    if (DRV_CONST(DRV_IPFIX_EXPORTREASON_NO_EXPORT) == p_data->export_reason)
    {
        p_data->export_reason = ctc_export_reason[p_ad_half0->exportReason];
    }
    p_data->tcp_flags = p_ad_half0->tcpFlagsStatus;

    if(0 == p_ad_half0->uDiscardInfoType)/* g1 */
    {
        p_data->drop_pkt_cnt[0] = (p_ad_half0->uDiscardInfo__0_28>>6)&0x3FF;
        p_data->drop_pkt_cnt[1] = p_ad_half0->uDiscardInfo__0_28>>22 | (p_ad_half0->uDiscardInfo__29_31<<7);
        p_data->drop_reason[0] = p_ad_half0->uDiscardInfo__0_28&0x3F;
        p_data->drop_reason[1] = (p_ad_half0->uDiscardInfo__0_28>>16)&0x3F;

    }
    else/* g2 */
    {
        drop_class_vector = p_ad_half0->uDiscardInfo__0_28 | (p_ad_half0->uDiscardInfo__29_31<<29);
        sys_tmm_ipfix_drop_clalssid_to_reason(lchip, drop_class_vector, p_data->drop_reason_bmp, CTC_INGRESS);
    }

    /*__TODO__*/
    if (p_usw_ipfix_master[lchip]->short_mode)
    {
        return CTC_E_NONE;
    }
    /*full*/
    dest_type = p_ad_full0->destinationType;
    if (0 == p_ad_full0->u1Type)
    {
        if (p_ad_full0->u1__0_7&0x1)
        {
            p_data->flags |= CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED;
        }
    }
    p_data->max_ttl = p_ad_full0->maxTtl;
    p_data->min_ttl = p_ad_full0->minTtl_0_3 | (p_ad_full0->minTtl_4_7<<4);
    p_data->start_timestamp = p_ad_full0->firstTs_0_9 | (p_ad_full0->firstTs_10_21<<10);
    p_data->last_timestamp = p_ad_full0->lastTs;
    if (p_data->last_timestamp < p_data->start_timestamp)
    {
        p_data->last_timestamp |= 0x400000;
    }
    if(p_data->drop_reason_bmp[0] || p_data->drop_reason_bmp[1] || p_data->drop_reason[0] || p_data->drop_reason[1])
    {
        p_data->flags |= CTC_IPFIX_DATA_DROP_DETECTED;
    }

    switch(dest_type)
    {
        case SYS_IPFIX_UNICAST_DEST:
            dest_chip = p_ad_full0->uDestinationInfo_>>9;
            p_data->dest_gport = p_ad_full0->uDestinationInfo_&0x1FF;
            p_data->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip,  p_data->dest_gport);
            break;
        case SYS_IPFIX_L2MC_DEST:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_;
            p_data->flags |= CTC_IPFIX_DATA_L2_MCAST_DETECTED;
            break;
        case SYS_IPFIX_L3MC_DEST:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_;
            p_data->flags |= CTC_IPFIX_DATA_L3_MCAST_DETECTED;
            break;
        case SYS_IPFIX_BCAST_DEST:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_;
            p_data->flags |= CTC_IPFIX_DATA_BCAST_DETECTED;
            break;
        case SYS_IPFIX_UNKNOW_PKT_DEST:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_;
            p_data->flags |= CTC_IPFIX_DATA_UNKNOW_PKT_DETECTED;
            break;
        case SYS_IPFIX_UNION_DEST:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_&0xFFF;
            p_data->flags |= CTC_IPFIX_DATA_APS_DETECTED;
            break;
        #if 0
        case SYS_IPFIX_ECMP_DEST:
            dest_chip = p_ad_full0->uDestinationInfo_>>9;
            p_data->dest_gport = p_ad_full0->uDestinationInfo_&0x1FF;
            p_data->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip, p_data->dest_gport);
            p_data->flags |= CTC_IPFIX_DATA_ECMP_DETECTED;
            break;
        #endif
        case SYS_IPFIX_LAG_DEST:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_>>8;
            p_data->flags |= CTC_IPFIX_DATA_LINKAGG_DETECTED;
            break;
        case SYS_IPFIX_CPU_DEST:
            p_data->dest_gport = (1<<CTC_TYPE_PORT_OFFSET|\
                        (p_ad_full0->uDestinationInfo_>>9)<<CTC_LOCAL_PORT_LENGTH);
            break;
        case 15:
            p_data->dest_group_id = p_ad_full0->uDestinationInfo_;
            if(p_data->dest_group_id)
            {
                p_data->flags |= CTC_IPFIX_DATA_L2_MCAST_DETECTED;
            }
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}


int32
sys_tmm_ipfix_decode_key_ad(uint8 lchip, ctc_ipfix_data_t* p_data, uint8 is_ad, void* p_key)
{
    if (is_ad)
    {
        sys_tmm_ipfix_decode_ad(lchip, p_data, p_key);
    }
    else
    {
        CTC_ERROR_RETURN(p_usw_ipfix_master[lchip]->callbacks_decode[p_data->key_type](lchip, p_data, p_key));
    }
    return CTC_E_NONE;
}

 uint8
_sys_tmm_ipfix_get_key_width(uint8 lchip, uint8 key_type)
{
    uint8 size = 0;

    switch (key_type)
    {
        case SYS_IPFIX_HASH_TYPE_L2L3:
        case SYS_IPFIX_HASH_TYPE_IPV6:
        case SYS_IPFIX_HASH_TYPE_NSH:
        case SYS_IPFIX_HASH_TYPE_NSH_SHORT:
            size = 4;
            break;
        case SYS_IPFIX_HASH_TYPE_L2:
        case SYS_IPFIX_HASH_TYPE_IPV4:
        case SYS_IPFIX_HASH_TYPE_MPLS:
        case SYS_IPFIX_HASH_TYPE_IPV6_SHORT:
        case SYS_IPFIX_HASH_TYPE_UDF:
            size = 2;
            break;
        case SYS_IPFIX_HASH_TYPE_IPV4_SHORT:
        case SYS_IPFIX_HASH_TYPE_UDF_SHORT:
            size = 1;
            break;
        default:
            size = 0;
            break;
            
    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))&&!p_usw_ipfix_master[lchip]->short_mode && key_type == SYS_IPFIX_HASH_TYPE_IPV6_SHORT)
    {
        size = 4;
    }
    return size;
}

int32
sys_tmm_ipfix_traverse_dma(uint8 lchip, void* cb, void* data, uint8 is_remove)
{
    int32 ret = 0;
    uint32 index = 0;
    uint32 count = 0;
    void* p_key = NULL;
    void* p_ad0 = NULL;
    void* p_ad1 = NULL;
    void* p_buffer = NULL;
    void* p_buffer_ad0 = NULL;
    void* p_buffer_ad1 = NULL;
    uint32 cfg_addr = 0;
    uint32 cfg_ad_addr0 = 0;
    uint32 cfg_ad_addr1 = 0;
    uint32 cmdr_flow_cnt = 0;
    uint32 cmdr_ad0 = 0;
    uint32 cmdr_ad1 = 0;
    ctc_ipfix_data_t ipfix_data;
    uint32 ipfix_max_entry_num = 0;
    uint32 next_index = 0;
    uint16 traverse_action = 0;
    uint8 sub_idx = 0;
    uint8 hash_type[4] = {0};
    uint32 temp_idx;
    sys_dma_tbl_rw_t dma_rw;
    drv_work_platform_type_t platform_type;
    uint32 entry_cnt = 0;
    uint32 loop = 0;
    uint32 key_index = 0;
    uint8 dir = 0;
    uint16 buff_size = 640;
    uint8 key_width = 0;
    uint8 idx_left = 0;
    uint32 use_io = 0;
    ctc_ipfix_traverse_t* p_data = (ctc_ipfix_traverse_t*)data;
    ctc_ipfix_traverse_t dump_info;
    ctc_ipfix_traverse_fn fn = cb;
    IpfixFlowEntryCounter_m flow_cnt;
    uint8 chan_en = 0;
    uint32 cmd = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&flow_cnt, 0, sizeof(flow_cnt));
    sal_memset(&dump_info, 0, sizeof(dump_info));
    dump_info.lchip_id = lchip;
    cmdr_flow_cnt = DRV_IOR(IpfixFlowEntryCounter_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmdr_flow_cnt), &flow_cnt);
    if(GetIpfixFlowEntryCounter(V, flowEntryCount_f, &flow_cnt) < SYS_IPFIX_DUMP_FLOW_CNT)
    {
        use_io = 1;
    }

    if(p_data->user_data != NULL)
    {
        traverse_action = *(uint16*)p_data->user_data;
    }

    sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));
    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer, buff_size*DRV_TABLE_ENTRY_SIZE(lchip,DsIpfixL3Ipv6HashKey_t));
    if (NULL == p_buffer)
    {
        return CTC_E_NO_MEMORY;
    }
    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer_ad0, buff_size*2*sizeof(DsIpfixSessionFullRecord0_m));
    if (NULL == p_buffer_ad0)
    {
        mem_free(p_buffer);
        return CTC_E_NO_MEMORY;
    }
    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer_ad1, buff_size*2*sizeof(DsIpfixSessionFullRecord1_m));
    if (NULL == p_buffer_ad1)
    {
        mem_free(p_buffer);
        mem_free(p_buffer_ad0);
        return CTC_E_NO_MEMORY;
    }
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL3Ipv4ShortHashKey_t, &ipfix_max_entry_num), ret, end_pro);/* get 120bits bits entry num */

    /* 1. p_data->start_index: based 120bit;
    2. 4 aligned processed by DMA, and use p_buffer for DMA, so the start index should be aligned ahead.
    3. e.g. start index 21,22,23, index is 20, idx_left is 1,2,3
    4. DMA process based on 480bit;    */
    idx_left = p_data->start_index % 4;
    if (idx_left)
    {
        index = (p_data->start_index / 4)*4;
    }
    else
    {
        index = p_data->start_index;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ipfix_max_entry_num = %d\n", ipfix_max_entry_num);
    if(index >= ipfix_max_entry_num)
    {
        goto end_pro;
    }
    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    sys_usw_dma_get_chan_en(lchip, SYS_DMA_TBL_RD_CHAN_ID, &chan_en);
    drv_get_platform_type(lchip, &platform_type);
    do
    {
        /*Notice: start_index and next_traverse_index is 120bits encoding index, for dma performance, every
        Dma operation is by 480bits */
        entry_cnt = ((index + buff_size*4) <= ipfix_max_entry_num)? buff_size : ((ipfix_max_entry_num - index) / 4);
        if (chan_en)
        {
            key_index = index;
            if (platform_type == HW_PLATFORM)
            {
                CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, DsIpfixL3Ipv6HashKey_t, key_index, &cfg_addr), ret, end_pro);
                CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, DsIpfixSessionFullRecord0_t, key_index, &cfg_ad_addr0), ret, end_pro);
                CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, DsIpfixSessionFullRecord1_t, key_index, &cfg_ad_addr1), ret, end_pro);
            }
            else
            {
                key_index = index;
                cfg_addr = (DsIpfixL3Ipv4ShortHashKey_t << 18) | key_index;
                cfg_ad_addr0 = (DsIpfixSessionHalfRecord0_t << 18) | key_index;
                cfg_ad_addr1 = (DsIpfixSessionHalfRecord1_t << 18) | key_index;
            }

            dma_rw.tbl_addr = cfg_addr;
            dma_rw.entry_num = entry_cnt;
            dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip,DsIpfixL3Ipv6HashKey_t);
            dma_rw.buffer = p_buffer;
            dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, DsIpfixL3Ipv6HashKey_t);
            CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw), ret, end_pro);  /* Ipe key */

            if(0 ==use_io)
            {
                dma_rw.tbl_addr = cfg_ad_addr0;
                dma_rw.entry_num = (entry_cnt)*2;
                dma_rw.entry_len = sizeof(DsIpfixSessionFullRecord0_m);
                dma_rw.buffer = (uint32*)((DsIpfixSessionFullRecord0_m*)p_buffer_ad0);
                dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, DsIpfixSessionFullRecord0_t);
                CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw), ret, end_pro); /* Ipe Ad */

                dma_rw.tbl_addr = cfg_ad_addr1;
                dma_rw.entry_num = (entry_cnt)*2;
                dma_rw.entry_len = sizeof(DsIpfixSessionFullRecord1_m);
                dma_rw.buffer = (uint32*)((DsIpfixSessionFullRecord1_m*)p_buffer_ad1);
                dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, DsIpfixSessionFullRecord1_t);
                CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw), ret, end_pro); /* Epe Ad */
            }
        }
        else
        {
            for (loop=0; loop<entry_cnt; loop++)
            {
                p_key = (uint8*)p_buffer + loop*DRV_TABLE_ENTRY_SIZE(lchip,DsIpfixL3Ipv6HashKey_t);
                cmd = DRV_IOR(DsIpfixL3Ipv6HashKey_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index+loop, cmd, p_key), ret, end_pro);

                if (0 == use_io)
                {
                    p_ad0 = (DsIpfixSessionFullRecord0_m*)p_buffer_ad0 + (loop*2);
                    p_ad1 = (DsIpfixSessionFullRecord1_m*)p_buffer_ad1 + (loop*2);
                    cmd = DRV_IOR(DsIpfixSessionFullRecord0_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index+loop, cmd, p_ad0), ret, end_pro);
                    cmd = DRV_IOR(DsIpfixSessionFullRecord1_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index+loop, cmd, p_ad1), ret, end_pro);
                }
            }
        }

        for(loop=0; loop < entry_cnt; loop++)
        {
            p_key = (uint8*)p_buffer + loop*DRV_TABLE_ENTRY_SIZE(lchip,DsIpfixL3Ipv6HashKey_t);
            if(0 == use_io)
            {
                p_ad0 = (DsIpfixSessionFullRecord0_m*)p_buffer_ad0 + (loop*2);
                p_ad1 = (DsIpfixSessionFullRecord1_m*)p_buffer_ad1 + (loop*2);
            }
            hash_type[0] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType0_f, p_key);
            hash_type[1] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType1_f, p_key);
            hash_type[2] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType2_f, p_key);
            hash_type[3] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType3_f, p_key);
            if ((hash_type[0] + hash_type[1] + hash_type[2] + hash_type[3]) == SYS_IPFIX_HASH_TYPE_INVALID)
            {
                idx_left = 0;
                continue;
            }

            if(use_io)
            {
                    p_ad0 = (DsIpfixSessionFullRecord0_m*)p_buffer_ad0;
                    p_ad1 = (DsIpfixSessionFullRecord1_m*)p_buffer_ad1;
                    cmdr_ad0 = DRV_IOR(DsIpfixSessionFullRecord0_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (key_index + loop*4), DRV_CMD_PP_EN(cmdr_ad0), p_buffer_ad0), ret, end_pro);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (key_index + loop*4) + 2, DRV_CMD_PP_EN(cmdr_ad0), (DsIpfixSessionFullRecord0_m*)p_buffer_ad0 + 1), ret, end_pro);

                     cmdr_ad1 = DRV_IOR(DsIpfixSessionFullRecord1_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (key_index + loop*4), DRV_CMD_PP_EN(cmdr_ad1), p_buffer_ad1), ret, end_pro);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (key_index + loop*4) + 2, DRV_CMD_PP_EN(cmdr_ad1), (DsIpfixSessionFullRecord1_m*)p_buffer_ad1 + 1), ret, end_pro);
            }

            for (sub_idx = idx_left; sub_idx < 4; sub_idx++)
            {
                key_width = _sys_tmm_ipfix_get_key_width(lchip, hash_type[sub_idx]);
                if((0 == key_width)||(sub_idx % key_width != 0))
                {
                    continue;
                }
                sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));
                ipfix_data.key_type = _sys_usw_ipfix_unmapping_key_type(lchip, hash_type[sub_idx]);
                p_usw_ipfix_master[lchip]->callbacks_decode[ipfix_data.key_type](lchip, &ipfix_data, (DsIpfixL3Ipv4ShortHashKey_m*)p_key + sub_idx);
                ipfix_data.dir = CTC_EGRESS;
                sys_tmm_ipfix_decode_ad(lchip, &ipfix_data, (DsIpfixSessionHalfRecord1_m*)p_ad1+sub_idx);
                ipfix_data.dir = CTC_INGRESS;
                sys_tmm_ipfix_decode_ad(lchip, &ipfix_data, (DsIpfixSessionHalfRecord1_m*)p_ad0+sub_idx);
                temp_idx = index + loop*4 + sub_idx;
                ipfix_data.key_index = temp_idx;
                IPFIX_TMM_TRAVERSE_TYPE_PROCESS(dump_info, ipfix_data.key_type, is_remove, dir);
                count += key_width;

                if (count >= p_data->entry_num)
                {
                    next_index = (index + loop*4) + (sub_idx + 1);
                    goto end_pro;
                }
            }
            next_index = (index + loop*4);
            idx_left = 0;
        }
        index += 4*entry_cnt;
        next_index = index;
    }while(index < ipfix_max_entry_num && count < p_data->entry_num);

end_pro:
    if(index >= ipfix_max_entry_num)
    {
        p_data->is_end = 1;
    }
    p_data->next_traverse_index = next_index;
    if(p_buffer)
    {
        mem_free(p_buffer);
    }
    if(p_buffer_ad0)
    {
        mem_free(p_buffer_ad0);
    }
    if(p_buffer_ad1)
    {
        mem_free(p_buffer_ad1);
    }
    return ret;
}

STATIC INLINE uint32
_sys_tmm_ipfix_uncombined_key(uint8 lchip, uint32* data_combined, uint32* data, uint32 tbl_id)
{
   uint8 index=0;
    if (DsIpfixSessionRecordMem0_t == tbl_id)
    {
        sal_memcpy((uint8*)data,data_combined,15);
        sal_memcpy((uint8*)data+16,(uint8*)data_combined+15,15);
    }
    else if (DsIpfixSessionRecordMem1_t == tbl_id)
    {
        sal_memcpy((uint8*)data, data_combined, 14);
        *((uint8*)data + 14) = *((uint8*)data_combined + 14)&0x3;

        for (index = 0; index < 14; index++)
        {
            *((uint8*)data + 16 + index) = *((uint8*)data_combined + 14 + index) >> 2 | (*((uint8*)data_combined + 15 + index) & 0x3) << 6;
        }
        *((uint8*)data + 30) = (*((uint8*)data_combined + 28 + index) >> 2)&0x3;
    }
    else
    {
        sal_memcpy((uint8*)data,data_combined,15);
        sal_memcpy((uint8*)data+16,(uint8*)data_combined+15,15);
        sal_memcpy((uint8*)data+32,(uint8*)data_combined+30,15);
        sal_memcpy((uint8*)data+48,(uint8*)data_combined+45,15);
    }
    return DRV_E_NONE;
}

int32
sys_tmm_ipfix_sync_data(uint8 lchip, void* p_dma_info)
{
    uint16 index = 0;
    uint16 loop = 0;
    ds_t ds_temp;
    sys_dma_info_t* p_info = (sys_dma_info_t*)p_dma_info;
    void *user_data = p_usw_ipfix_master[lchip]->cb_buf;  /* per 64 entry call user callback function */
    MsIpfixDmaInfo_m* p_temp_fifo = NULL;
    CpuInfoIpfix_m* p_ipfix_cpu_info = NULL;
    uint8 is_ingress = 0 ;
    uint8 hash_type  = 0;
    uint8 sys_dmainfo_reason = 0;

    ds_t hash_key;
    ds_t ingress_ad;
    ds_t egress_ad;
    uint32 im_flow_enable = 0;
    ctc_ipfix_data_t* user_info = NULL;
    ctc_ipfix_data_t* user_info_next = NULL;
    int32 ret = CTC_E_NONE;
    CTC_ERROR_RETURN(SYS_CB(SYS_CB_NPM_IM_GET_EN, lchip, 0, &im_flow_enable));
    p_usw_ipfix_master[lchip]->cb_buf_status = 1;
    for (index = 0; index < p_info->entry_num ; index++)
    {
        SYS_IPFIX_LOCK(lchip);
        user_info = (ctc_ipfix_data_t*)user_data + loop;
        sal_memset(user_info, 0, sizeof(ctc_ipfix_data_t));
        p_ipfix_cpu_info = (CpuInfoIpfix_m*)((uint8*)(p_info->p_data)+index* TABLE_ENTRY_SIZE(lchip, CpuInfoIpfix_t));
        p_temp_fifo = (MsIpfixDmaInfo_m*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_ipfix_cpu_info);
        GetMsIpfixDmaInfo(A, ipfixHashKey_f, p_temp_fifo, &ds_temp);
        _sys_tmm_ipfix_uncombined_key(lchip, (uint32*)ds_temp, (uint32*)&hash_key, DsIpfixL2L3HashKey_t);
        GetMsIpfixDmaInfo(A, ipfixIngressAd_f, p_temp_fifo, &ds_temp);
        _sys_tmm_ipfix_uncombined_key(lchip, (uint32*)ds_temp, (uint32*)&ingress_ad, DsIpfixSessionRecordMem0_t);
        GetMsIpfixDmaInfo(A, ipfixEgressAd_f, p_temp_fifo, &ds_temp);
        _sys_tmm_ipfix_uncombined_key(lchip, (uint32*)ds_temp, (uint32*)&egress_ad, DsIpfixSessionRecordMem1_t);
        user_info->key_index = GetMsIpfixDmaInfo(V, keyIndex_f, p_temp_fifo);
        sys_dmainfo_reason = *(uint32*)p_temp_fifo&0xF;
        hash_type = hash_key[0]&0x7;

        user_info->key_type = _sys_usw_ipfix_unmapping_key_type(lchip,hash_type);
        p_usw_ipfix_master[lchip]->callbacks_decode[user_info->key_type](lchip, user_info, &hash_key);
        user_info->dir = CTC_INGRESS;
        sys_tmm_ipfix_decode_ad(lchip, user_info, &ingress_ad);
        if (user_info->export_reason)
        {
            is_ingress = 1;
        }
        user_info->dir = CTC_EGRESS;
        sys_tmm_ipfix_decode_ad(lchip, user_info, &egress_ad);
        if (is_ingress)
        {
            user_info->dir = CTC_INGRESS;
        }

        if(CTC_IPFIX_REASON_DUMP == ctc_export_reason[sys_dmainfo_reason])
        {
            user_info->export_reason = CTC_IPFIX_REASON_DUMP;
            user_info->dir = CTC_INGRESS;
        }

        _sys_usw_ipfix_export_stats(lchip, user_info->export_reason,
        (user_info->dir == CTC_INGRESS? user_info->pkt_count : user_info->e_pkt_count),
        (user_info->dir == CTC_INGRESS?user_info->byte_count:user_info->e_byte_count));
        SYS_IPFIX_UNLOCK(lchip);

        if (im_flow_enable)
        {
            ctc_pkt_rx_t *pkt_rx = NULL;
            uint64 ts_ns = 0;
            sys_usw_ipfix_delete_entry_by_index(lchip, user_info->key_type, user_info->key_index, 0);
            MALLOC_ZERO(MEM_IPFIX_MODULE, pkt_rx, sizeof(ctc_pkt_rx_t));
            if (pkt_rx)
            {
                pkt_rx->rx_info.reason = CTC_PKT_CPU_REASON_NPM_IM_DELAY;
                ts_ns = p_info->nanoseconds/100000000ULL*100000000ULL + (user_info->last_timestamp<<5)%100000000ULL;
                pkt_rx->rx_info.ptp.ts.nanoseconds = ts_ns%1000000000ULL;
                pkt_rx->rx_info.ptp.ts.seconds = p_info->seconds + ts_ns/1000000000ULL;
                ts_ns += (user_info->last_latency+1)<<5;
                pkt_rx->rx_info.ptp.egs_ts.nanoseconds = ts_ns%1000000000ULL;
                pkt_rx->rx_info.ptp.egs_ts.seconds = p_info->seconds + ts_ns/1000000000ULL;
                SYS_CB(SYS_CB_NPM_IM_GET_FLOW_ID, lchip, user_info->logic_port, &pkt_rx->rx_info.efd_flow_id);
                sys_usw_packet_usr_rx_cb(lchip, pkt_rx);
                mem_free(pkt_rx);
            }
            else
            {
                ret = CTC_E_NO_MEMORY;
                goto end_pro;
            }
        }
        else if (p_usw_ipfix_master[lchip]->max_export_entry_num == (loop+1))
        {
            user_info->p_next = NULL;

            if (p_ipfix_cb_mutex)
            {
                sal_mutex_lock(p_ipfix_cb_mutex);
            }
            p_usw_ipfix_master[lchip]->ipfix_cb((ctc_ipfix_data_t*)user_data, p_usw_ipfix_master[lchip]->user_data);
            if (p_ipfix_cb_mutex)
            {
                sal_mutex_unlock(p_ipfix_cb_mutex);
            }
            loop = 0;
            sal_memset(user_data,0,sizeof(ctc_ipfix_data_t)*p_usw_ipfix_master[lchip]->max_export_entry_num);
        }
        else
        {
             user_info_next = (ctc_ipfix_data_t*)((uint8*)user_info + sizeof(ctc_ipfix_data_t));
             user_info->p_next = user_info_next;
             loop++;
        }
    }

    if(loop)
    {
        user_info->p_next = NULL;
        if (p_ipfix_cb_mutex)
        {
            sal_mutex_lock(p_ipfix_cb_mutex);
        }
        p_usw_ipfix_master[lchip]->ipfix_cb((ctc_ipfix_data_t*)user_data, p_usw_ipfix_master[lchip]->user_data);
        if (p_ipfix_cb_mutex)
        {
            sal_mutex_unlock(p_ipfix_cb_mutex);
        }
    }
end_pro:
    p_usw_ipfix_master[lchip]->cb_buf_status = 0;
    return ret;
}


int32
sys_tmm_get_hw_drop_class_id(uint8 lchip, uint32 ctc_drop_reason, ctc_direction_t dir, uint32* p_classid)
{
    uint32 cmd = 0;
    uint32 loop = 0;
    uint32 sys_drop_bmp[8] = {0};

    sal_memset(sys_drop_bmp, 0, sizeof(sys_drop_bmp));
    sys_tmm_map_drop_reason_ctc_to_sys(ctc_drop_reason, sys_drop_bmp);

    if (dir == CTC_INGRESS)
    {
        for (loop = SYS_TMM_DISCARD_IPE_START; loop <= SYS_TMM_DISCARD_IPE_END; loop++)
        {
            if (CTC_BMP_ISSET(sys_drop_bmp, loop))
            {
                cmd = DRV_IOR(IpfixEngineDiscardMapCtl0_t, IpfixEngineDiscardMapCtl0_discardTypeClassId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), p_classid));
                break;
            }
        }
    }
    else
    {
        for (loop = SYS_TMM_DISCARD_EPE_START; loop <= SYS_TMM_DISCARD_EPE_END; loop++)
        {
            if (CTC_BMP_ISSET(sys_drop_bmp, loop))
            {
                cmd = DRV_IOR(IpfixEngineDiscardMapCtl1_t, IpfixEngineDiscardMapCtl1_discardTypeClassId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (loop - (SYS_TMM_DISCARD_IPE_END + 1)), DRV_CMD_PP_EN(cmd), p_classid));
                break;
            }
        }
    }
    return CTC_E_NONE;
}

int32
sys_tmm_ipfix_cb_init(uint8 lchip)
{
    /*encode*/
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_encode_l2_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_encode_l2l3_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV4] = p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_encode_v4_short_key : _sys_usw_ipfix_encode_ipv4_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV6] =  p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_encode_v6_short_key : _sys_usw_ipfix_encode_ipv6_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MPLS] = p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_encode_v4_short_key : _sys_usw_ipfix_encode_mpls_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_UDF] = p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_encode_udf_short_key : _sys_tmm_ipfix_encode_udf_key;

    /*decode*/
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MAC] = _sys_tmm_ipfix_decode_l2_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_tmm_ipfix_decode_l2l3_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV4] = p_usw_ipfix_master[lchip]->short_mode ? _sys_tmm_ipfix_decode_v4_short_key : _sys_tmm_ipfix_decode_ipv4_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV6] = p_usw_ipfix_master[lchip]->short_mode ? _sys_tmm_ipfix_decode_v6_short_key: _sys_tmm_ipfix_decode_ipv6_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MPLS] = p_usw_ipfix_master[lchip]->short_mode ? _sys_tmm_ipfix_decode_v4_short_key : _sys_tmm_ipfix_decode_mpls_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_UDF] = p_usw_ipfix_master[lchip]->short_mode ? _sys_tmm_ipfix_decode_udf_short_key : _sys_tmm_ipfix_decode_udf_key;

    /*set hash select*/
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_set_l2_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_set_l2l3_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV4] = p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_set_v4_short_hash_sel : _sys_usw_ipfix_set_ipv4_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV6] =  p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_set_v6_short_hash_sel : _sys_usw_ipfix_set_ipv6_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MPLS] =  p_usw_ipfix_master[lchip]->short_mode?
    _sys_tmm_ipfix_set_v4_short_hash_sel : _sys_usw_ipfix_set_mpls_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_UDF] = _sys_tmm_ipfix_set_udf_hash_sel;

    /*get hash select*/
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_get_mac_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_get_l2l3_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_get_v4_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_get_v6_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_get_mpls_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_UDF] = _sys_usw_ipfix_get_udf_hash_sel;
    return CTC_E_NONE;
}

#endif
#endif

